1、会话的概念
会话(session),指的是web应用程序中客户端浏览器发出请求到服务器响应客户端请求的全过程。
2、什么是会话跟踪
对同一个用户对服务器的连续的请求和接收响应的监视。
3、为什么需要会话跟踪
浏览器与服务器之间的通信是通过HTTP协议进行通信的,而HTTP协议是“无状态”的协议(早期主要用于web端获取内容,浏览了就结束,没有考虑交互的场景,所以服务器不会保留与用户交易的任何状态),客户端与服务器之间的联系是离散的、非连续的。
多次请求,无法根据前后的请求来判断是否是同一个用户,面对越来越多的交互场景,会话跟踪技术应运而生。
4、会话跟踪技术
从原理上分析,一次请求和响应主要参与的有服务器、客户端,以及通信的HTTP协议,多以分别从这三方面考虑,会话跟踪技术主要有以下四种:
(1)Cookie
(2)url重写
(3)隐藏表单域
(4)Session
4.1 Cookie
是最常用的跟踪用户会话的方式,在客户端保持会话跟踪的解决方案,Cookie是以键值对形式存在片段信息,保存在客户端浏览器。
当用户第一次请求服务时,Cookie信息会随着服务器端的响应发送给客户端浏览器,然后客户都浏览器会把Cookie保存起来,当下一次客户端在发起请求时携带此信息作为用户的唯一标识发送给服务器。
Http的Cookie规范
- 1个Cookie的大小不超过4KB
- 1个服务器最多向一个浏览器保存20个Cookie
- 1个浏览器最多可以保存300个Cookie
Cookie的用途
- 服务器使用Cookie来跟踪客户端状态
- 保存部分业务信息
- 显示上次登录信息
4.2 Session
Session是指使用后HttpSession对象实现会话跟踪的技术,是一种在服务器端保持会话跟踪的解决方案。
HttpSession是由JavaWeb提供的对象,是javax.servlet.http.HttpSession接口的实例,用来会话跟踪的类,也称为会话对象。是服务器端对象,保存在服务器端中。
HttpSession对象会在用户第一次访问服务器时由容器创建(注意只有访问JSP,Servlet等程序时才会创建,只访问HTML,IMAGE等静态资源并不会创建),当用户调用其失效方法(invalidate()方法)或超过其最大不活动时间会失效。在此期间,用户与服务器之间的多次请求都属于同一个会话。
比如,用户认证流程,客户端向服务器端发送请求,接收到请求后,Servlet容器为HttpSession对象分配一个唯一的SessionID,将其作为Cookie(或者作为URL的一部分,利用URL重写机制)发送给浏览器,浏览器在内存中保存这个Cookie。当客户再次发送HTTP请求时,浏览器将Cookie随请求一起发送,Servlet容器从请求对象中获取SessionID,然后根据SessionID找到对应的HttpSession对象,从而得到客户的状态信息。
4.3 隐藏表单域
隐藏表单域是利用 HTML 中的隐藏域,在网页表单内隐藏某些客户端的信息。在提交表单时,要将指定的名称和值自动包括在请求实体中,这些信息会随客户端的请求信息一起传送给服务器,服务器通过获取的这些信息来进行会话跟踪。
这些识别信息是隐藏的,所以不会在客户端的浏览器页面上显示,但是,如果查看 HTML 的源文件,是可以看到这些隐藏字段的,这样很可能会导致用户资料的泄露。显然,这是使用隐藏域方式的一个缺陷
<form name="testform" action="/xxx">
//隐藏域
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
很显然,仅当每个页面都是由表单提交而动态生成时,才能使用这种方法。比如,单击常规的超文本链接并不产生表单提交,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中。
优点
- 存储内容不限;
- 浏览器不支持 cookie 或在用户禁用 cookie 的情况下,这种方案也能够工作;
缺点
- 依赖表单提交;
- 如果大量隐藏表单且value数据量较大,会影响页面渲染
4.4 URL重写
客户程序在每个URL的尾部添加一些额外数据(以键值对的形式传递),这些数据标识当前的会话,服务器将这个标识符与它存储的用户相关数据关联起来。通常是添加 sessionID作为会话信息的标识。
http://172.23.22.58:8081/jjyhf;jsessionid=123456789
对于重写的URL,服务器端程序要做许多简单但是冗长乏味的处理任务。
- 通过Servlet容器解释URL,将对应的会话信息SessionId从URL中读取出来
- 通过SessionId将请求和特定的Session关联,确认为同一会话
- 完成服务处理,发送给服务端的URL也进行重写编码
优点
- 浏览器不支持 cookie 或在用户禁用 cookie 的情况下,这种方案也能够工作
缺点
- 必须对所有指向本 Web 站点的 URL 进行编码;
- 参数在URL中,有长度限制;
- 如果用户离开了会话并通过书签或链接再次回来,由于存储下来的链接含有错误的标识信息,会话的信息会丢失;
- 用户 ID 及登录密码等重要信息可能以参数的形式暴露在URL上,造成安全隐患
5、作用域
-
page:只在当前页面有效(页面范围)
page.setAttribute(“userType”,“VIP”) -
request:在一个请求中有效(请求范围)
request.setAttribute(“userType”,“VIP”); -
session:会话范围。在一个会话中有效
session.setAttribute(“userType”,“VIP”); -
application:应用程序范围(全局的)
application.setAttribute(“userType”,“VIP”);
6、页面跳转方式
-
页面重定向:resp.sendRedirect()。在重定向会产生两个request对象,两个request对象是不同的,所携带的请求信息也是不同。属于客户端跳转
-
请求转发:只产生了一个request对象。属于服务器端跳转。在跳转中使用的是同一个request对象,所以携带的请求信息是相同的是通过RequestDispatcher对象的getRequestDispatcher()方法进行请求转发