Session的介绍
Session(会话),是Web开发中的一种会话状态跟踪技术。
Cookie也是一种会话跟踪技术,但俩者有区别。前者是将会话状态保存在服务器,而后者是将会话状态保存在客户端。
这里巩固会话概念:从浏览器发出一次请求开始,直到关闭浏览器,即一次会话的完成。
Session对象创建
Session以javax.servlet.http.HttpSession的接口对象形式出现,所以创建Session对象不能用new。
在HttpServletRequest接口中有俩个创建Session对象的方法。
1.无参的方法
getSession();返回当前Session对象,若当前无Session对象,则创建一个Session对象。
2.有参的方法
getSession(boolean create);返回当前Session对象,若当前无Session对象,并且参数为true,则创建一个Session对象。若当前无Session对象,并且参数为false,则不创建对象,返回Null。
Session域属性空间的操作
Session是一个专门用于存放数据的集合,我们一般称这个用于存放数据的内存空间为域属性空间,简称域。HttpSession中具有三个方法,专门对该域属性空间中数据进行读、写操作。
1.public void setAttribute(String name,Object value)
该方法用于向Session的域属性空间中放入指定名称、指定值的域属性。
2.public void getAttribute(String name)
该方法用于从Session的域属性空间中读取指定名称的域属性值。
3.public void remove Attribute(String name)
该方法用于从Session的属性空间中删除指定名称的域属性。
Session 是跨请求的数据传递。
/** Servlet1
* Reaquest与Session域作用范围对比Demo
*/
//获取用户提交的参数
String username = request.getParameter("username");
//将参数放入request域
request.setAttribute("userRequest",username);
//获取Session对象
HttpSession session = request.getSession();
//将参数放入Session域
session.setAttribute("userSession",username);
/** Servlet2
* Reaquest与Session域作用范围对比Demo
*/
//从request域中读取指定属性
String userRequest = request.getAttribute("userRequset");
//获取Session
HttpSession session=request.getSession(false);
//从Session中读取指定属性
String userSession = null;
if(session != null){
userSession = (String)session.getAttribute("userSession");
}
Session的工作原理(重要)
疑问
在服务器中系统会为每个会话维护一个Session。不同的会话,对应不同的Session。
疑问:
1.系统是如何识别各个Session对象的?
2.如何做到在同一个会话过程中,一直使用的是同一个Session对象?
解剖
底层工作的流程步骤:
1.将Session对象写入Session列表
用户第一次提交请求时,服务的Servlet中执行到创建Session对象(request.getSession)语句后,会自动生成一个Map.Entry对象,其中key为一个根据某种算法新生成的JSessionID,value则为新创建的HttpSession对象。
当前应用中的Session是以Map形式进行管理的,这个Map称为Session列表。该Map的key为一个32位长度的随机字符串,这个随机字符串称为JSession,value则为Session对象的引用。
2.服务器生成并发送Cookie
在将Session信息写入Sessio列表之后,系统还会自动将“JSESSIONID”作为name,这个32位长度的随机串作为value,以Cookie的形式存放到响应报头中,并随着响应,将该Cookie发送到客户端。
3.客户端接收并发送Cookie
客户端接收到这个Cookie后会将其存放到浏览器的缓存中。即只要客户端浏览器不关闭,浏览器缓存中的Cookie就不会消失。
当用户提交第二次请求时,会将缓存中的这个Cookie,伴随着请求的头部信息,一块发送到服务器。
4.从Session列表中查找
服务端从请求中读取到客户端发送来的Cookie,并根据Cookie的JSESSIONID的值,从Map中查找相应的key,所对应的value,即Session对象。然后,对该Session对象的域属性进行读写操作。
Session的失效
Web开发中引入的Session超时的概念,Sesison的失效指的就是Session的超时。
在web.xml中可以通过标签设置Session的超时时间,单位为分钟。系统默认的Se’s’si’o’n超时时间为30分钟。需要注意的时,这个时间是从最后一次被访问开始计时的,而不是从Session被创建开始计时。
客户端关闭浏览器其实并不是意味着一次会话的解释,
对服务器来说Session的失效才是一次会话的结束。
<!-- web.xml文件中设置Session的失效时间-->
<session-config>
<session-timeout>90</session-timeout>
</session-config>
即使未达到失效时限,也可以通过代码提前使得Session失效。在HttpSession接口中有invalide()方法,可以实现Session失效。
//获取Session对象
HttpSession session = request.getSession();
//设置使得Session失效
session.invalidate();
/* 这里需要注意是invalidate()方法只是让Session失效,
* 且解绑Session对象上所有的对象,
* Session中不存在数据了,
* 但Session对象并不是Null。
*/
当客户端Cookie禁用后
服务器与客户端之间
服务器因接收不到客户端请求时,发送来的(Cookie:JSESSIONID)所以服务器会一直认为这是一次新的会话,第一次请求。以至于在servlet中创建Session对象,会让服务器的一直的往客户端发送Cookie形式,带有32位长度随机字符串。
但是在获取到JSESSIONID的情况下,能够继续操作当前Sesison,直至该Session失效。
重定向跳转时
因为客户端禁用了Cookie,导致重定向跳转,Session无法跟踪解决方法。(但不安全,暴露了Session对象)
/*
* doGet()
*/
//获取Session对象
HttpSession session = request.getSession();
//拼接Uri方式,进行重定向跳转.
String uri = request.getContextPath() + "/Servlet2";
//解决Cookie禁用后,Session的跟踪问题。就算不禁用Cookie也不影响使用。
uri = response.encodeRedirectURL(uri);
response.sendRedirect(uri);
非重定向跳转时
因为客户端禁用了Cookie,导致超链接跳转,Session无法跟踪解决方法。(不安全,暴露了Se’ssion对象)
/*
* doGet()
*/
//获取Session对象
HttpSession session = request.getSession();
//设置响应字符编码
response.setContentType("text/html;charset=utf-8");
//打印在客户端
PrintWriter out = response.getWriter();
//设置Uri.
String uri = "/Servlet2";
//解决Cookie禁用后,非重定向时的Session的跟踪问题。
uri = response.encodeURL(uri);
out.println("<a href='"+uri+"'>超链接</a>到Servlet2");