你真的了解web开发中的会话技术吗?

大家好,这里是睿智的仓鼠。

对于程序设计来说,真正的难点其实在于原理和底层,而不在于代码实现。作为开发人员,只有明确了一门技术诞生的原因、独有的特点以及合适的使用场景,才能更好地在业务中进行代码实现。本文主要介绍了会话技术的基本逻辑,代码实现会在之后的文章中进行介绍。

1、什么是会话

所谓的会话过程就是指从打开浏览器到关闭浏览器的过程。

一次会话:浏览器第一次给服务器资源发送请求,会话建立;直到有一方断开(大多数时候是浏览器断开与服务器的连接),会话结束。

一次会话范围内,可以包含多次请求,收到多次响应。


2、关于Http协议的“无状态”特性

HTTP协议是无状态的,也就是每次请求和响应之间是互相独立的,服务器并不知道客户端的历史请求记录,因此无法共享数据。

按照原始的HTTP协议,一个用户向服务器发送了一次请求,服务器处理了结果,并做出了响应。该用户继续向服务器发送请求,但服务器此时并不知道,这两个请求是否是同一个浏览器或用户发出来的。

有状态的会话是指,浏览器发送的每一次请求,每一个会话都要有唯一的标识来唯一标识自己,当浏览器发送请求的时候就带上这个标识来让服务器识别,从而实现有“状态”的会话。

3、什么是会话技术

现如今我们不管是设计还是使用web应用时,总是离不开多次请求间共享数据这个需求,比如网上购物时添加购物车、浏览论坛时收藏文章等场景,都需要整合多个不同请求的数据。

举个生活中的例子
比如淘宝网,用户访问首页后可以点击多个商品的链接,加入到购物车中,再到购物车的页面集体结算。显然这属于多次请求,而且请求的是服务器上不同的资源。如果单纯地记录每次请求的数据,就无法实现像淘宝购物车这样的操作。

我们必须记录一个完整的购物周期内,用户的添加购物车操作。而且,必须保存这些数据,以便用户下次访问时继续操作购物车。

会话技术的目的就是,在一次的会话范围内的多次请求间,共享数据。

一个完整的购物周期,其实就是一次会话。它开始于用户访问淘宝网,终止于用户退出浏览器或关闭所有淘宝有关的标签页,与淘宝网断开连接。

而保存一次会话中的用户数据,就需要使用到会话技术

在Java语言中,会话技术分为两类:客户端会话技术(Cookie)服务器端会话技术(Session)。Cookie和Session作为域对象,相当于为http协议添加了保存http状态信息的状态机制,从而为使用http协议的web应用实现了状态判断。

cookie和session是浏览器与服务器交互的一种广泛使用的规范,只要浏览器或服务器遵守了该规范,我们就能使用cookie和session。

举个生活中的例子
比如你去商店购物,而这家商店不区分新老客户,一律视为新客户,这就是无状态的。

商店想要带动顾客消费的积极性,决定推出会员积分制度。商店想了两种办法:

第一种,给顾客发放会员卡,会员卡里存储着顾客的消费信息和积分。这就是cookie技术。

第二种,顾客每次购物时报手机号,商店的数据库负责存储该顾客的消费信息和积分。这就是session技术。

其实,这些机制都是在无状态的传统购买过程中加入了一点东西,使整个过程变得有状态。Web应用就是这样的。


看到这里,相信你会产生一个疑问:既然需求如此旺盛,那么http协议在设计之初为什么选择设计成无状态的简单形式呢?

首先,我们要知道,http确实是无状态的,它不会因为cookie和session的加入而变成有状态的。我们的逻辑始终不能发生错误:我们要设计一个web应用,我们选择了http协议,它是无状态的,但我们需要设计出的web应用是有状态的,所以我们引入了cookie、session这个机制,来实现有状态的web应用。从始至终,我们都没有改变http协议,我们只是在使用时,丰富了使用它的web应用的功能。

那么,为什么现在我们所需要的web应用是有状态的,给它提供的底层协议却是无状态的?如果网络协议原生支持状态机制,那么我们也不需要花精力在cookie和session上了。

这个问题,可以从历史的角度去思考。在web应用还很简单的时候,这个应用只是被用来浏览内容。如果只是浏览内容的话,无状态的协议已经够了,这样实现可以减轻实现的负担,因为有状态的协议实现起来代价相对来说是很高的(要维护状态,服务器要负担起很多的东西,例如内存空间)。但现在看来,web应用是大部分是需要状态的,那么是否应该改变这个协议,来让它变成一个有状态的协议呢?我给出的答案是,不应该。

首先,web应用与文件传输是不同的。众所周知,TCP协议是有状态的,它通过三次握手可以建立起一次稳定的有状态的传输。但TCP协议的目的,其实和web应用有一些区别:

文件传输,从开始到结束是一个任务驱动的动作,所以这类动作不会在资源占有上浪费太多次要空间。而web应用中,用户在访问一个页面后,可能在某个页面上逗留很久才跳转到另外一个页面,如果在这两个页面(两个http请求应答)之间维持状态,其代价是非常高的。

其次,历史上的http无状态,而应用需求对http提出有状态的要求,按照软件领域的通常做法是,不在http协议本质上作太大的改动,以达到兼容过去的软件,而在http上再加上一层,来拓展它的功能。这一层,就是cookies,session等。


看到这里,如果你熟悉web应用的开发流程,相信你还有一个疑问:为什么必须使用cookie&session来作为域对象?request对象和servletContext对象也可以作为域对象,那么它们能够替代cookie与session的功能吗?

答案自然是否定的,但我们要理解为什么。

想象一个简单的购物系统,它包括一个购物页面(浏览器),一个购物车servlet与一个结算servlet(服务器)。

首先来看request,request的作用域是一次请求范围内,我们可以认为,它是请求私有的。每一次请求都会创建一个新的request。我们通过request域,可以获取到用户第一次添加进购物车的数据;如果我们要获取第二次添加购物车的请求数据,其实也可以做到,那就是将上一个request域中的数据与新的数据拼接,一并存入新的这个request域中,但这种做法很蠢,而且经过结算servlet后,request中的数据还是会全部丢失,没办法持续保存。

再来看servletContext。它代表整个web应用,我们可以认为,它是服务器私有的。所以,如果使用servletContext域来存储购物车内容,那么好处是确实不会发生数据丢失的情况,除非淘宝网服务器全部宕机。坏消息是,所有淘宝用户将共享同一个购物车,这简直太可怕了。

而cookie和session就可以很好地解决这个问题,因为这就是它们被设计出来的原因。具体原理不过多赘述,在详细讲解cookie和session时会涉及到。我们按照上面的思路,继续从实现上来研究这个事情。

使用Cookie(客户端技术),添加一包瓜子进购物车,就会把瓜子这个对象存入开辟的Cookie空间中,Cookie空间为此对象绑定一个唯一的标识,然后以响应头方式返回给客户端。当再去添加木屑的时候,木屑对象会带着这个唯一标识以请求头的方式存入到Cookie空间中,同时为它绑定唯一的标识。因为Cookie域保存在自己浏览器内部,所以与别人互不干扰。但是cookie也有缺点:第一,因为交互都在请求头响应头上,所以存储大小肯定有限制,不能存更多的信息。第二,因为cookie是浏览器维护的,面向用户,所以不安全。

鉴于Cookie的缺点,Session(服务器技术)才产生。session的解决办法是,cookie里只存一个标识,一个客户端服务端用来交互的标识,其他重要信息都存在服务器的一个对象里,浏览器传来cookie的标识,服务器就拿到这个标识进行比对,比对上了就可以拿出对应的信息,这个对象就是session,这个标识就是sessionid。和Cookie一样,添加一包瓜子,就会把瓜子这个对象存入到开辟的Session空间中, Session空间为此对象生成一个唯一的Key值,当再去添加木屑的时候,会带着这个唯一的Key值存入到Cookie空间中,同时为它绑定唯一的Key值。但要注意,Session仅仅只是保存记录的载体,是依赖于Cookie的,Cookie才是实现会话技术的基础,而session只是为了解决数据安全和浏览器压力才应运而生的技术。

看到这里,相信你对会话技术已经有了初步的了解。既然我们已经明确了会话技术的前因后果,那么接下来就到了实践出真知的时候了。在下一篇文章中,我会对上文提到的内容做简单的代码实现,供大家学习参考。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值