什么是session呢?了解session之前,先要简单了解http协议。
http协议是面向无连接的协议,一次请求,一次操作,然后就结束了,是没有状态的。就是说,用户请求一次,server响应一次,完了它就翻脸不认人了。
然而实际上用户往往需要多次请求服务器才能完成一次“操作事件”,比如购物车,你先要请求server,浏览一下物品清单,然后要把物品放进购物车,最后再支付,至少需要和server交互3次以上,并且这3次请求,server都要知道是来自同一个用户。怎么办呢?使用session会话跟踪。
网上有很多文章说,Servlet/Jsp的会话管理技术主要有4种:URL重写,Cookie,隐藏表单域以及HttpSession。这个HttpSession不就是session是j2ee的实现规范嘛,怎么算一种会话管理技术?我搞不懂。。。
我看了j2ee 1.4 编程指南,传统上通常有3种会话跟踪:Cookie、隐藏表单和URL重写。
还有一种基于https的SSL会话,SSL(Secure Sockets Layer,安全套接字层)是HTTPS协议使用的一种加密技术,内建了会话跟踪功能,Servlet容器可以非常容易的使用这些数据建立会话跟踪。(但是HTTPS不是规范要求Servlet必须支持的协议) 因为HTTP是一种基于请求响应的协议,因此会话只有在客户端加入它以后才被新建立。当会话跟踪信息被成功的返回给服务器以指示会话给建立时客户端才算加入了一个会话。如果客户端没有加入会话,那么下一次请求不会被认为是会话的一部分。如何客户端还不知道会话或者客户端选择不加入一个会话,那么会话被认为是新的。开发者必须自己设计自己的应用中的会话处理状态,在什么地方没有加入会话,什么地方不能加入会话以及什么地方不需要加入会话。
重点说Cookie、隐藏表单和URL重写:
Cookie是用来干什么的?
Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器。
规范要求所有的Servlet都必须支持cookie。一般默认使用Cookie实现会话跟踪(这个要注意,我发现大部分项目都没有专门重写URL去实现会话跟踪,包括很多大型网站,像baidu贴吧,新浪微博,甚至是Google)。
关于是否应当使用cookie有很多的争论,因为一些人认为cookie可能会造成对隐私权的侵犯(当然事实上尚未发现)。有鉴于此,大部分浏览器允许用关闭cookie功能,然而这使我们跟踪会话变得更加困难。如果不能依赖cookie的支持又该怎办呢?
j2ee guide上提到了一个利用隐藏表单的方法,就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如下面的表单
<form name="testform" action="/xxx">
<input type="text">
</form>
在被传递给客户端之前将被改写成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
这种技术现在已较少应用,知道有这么回事就OK了。
还有一种比较可行的办法是重写URL(URL Rewriting),就是在所有的页面跳转上加上 encodeURL() 或者 encodeRedirectURL(),容器会自动在请求url路径的后面追加上jsessionid=xxxxxxxxxxxxxxx。为了在整个交互过程中始终保持状态(不脱离会话),就必须在每个客户端可能请求的路径后面都包含这个session id,即每次请求都要重写url。
可以自己做一个简单的小例子来验证一下:
1.建一个web工程
2.在WebRoot下面,加入两个jsp
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'index.jsp' starting page</title> </head> <body> This is a index.jsp<br> Session Id : <%=session.getId()%><br> <a href="test.jsp">to test.jsp</a> </body> </html>test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'test.jsp' starting page</title> </head> <body> This is a test.jsp<br> Session Id : <%=session.getId()%><br> <a href="index.jsp">to index.jsp</a> </body> </html>启动服务后,访问index.jsp,如下:
将index.jsp中的<a href="test.jsp">to test.jsp</a> 改为
<a href="<%=response.encodeRedirectURL("test.jsp")%>">to test.jsp</a>
将test.jsp中的<a href="index">to index.jsp</a> 改为
<a href="<%=response.encodeRedirectURL("index.jsp")%>">to index.jsp</a>
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。