Session 与 cookie

一Session:保存在服务端的会话信息

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。

当程序需要为某个客户端的请求创建一个Session的时候,服务器首先检查这个客户端的请求里是否已包含一个Session标识(称为Sessionid),如果包含了一个Sessionid则说明以前已经为此客户端创建过Session,服务器就根据Sessionid把这个Session检索出来使用(如果检索不到,可能会新创建一个),如果客户端请求中没有包含Sessionid,则为此客户创建一个Session并且生成一个与此Session相关联的Sessionid,Sessionid的值应该是一个既不会重复,又不容易被找到规律而被仿造的字符串,这个Sessionid将在本次响应中被返回给客户端保存。

保存这个Sessionid的方式一般采用Cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。一般这个Cookie的名字都类似于SEEESIONID,例如weblogic生成的Cookie:

JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字的是JSESSIONID。

Session的常用方法

session.getId()返回Session的ID。该ID由服务器自动创建,不会重复

Session对浏览器的要求

虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。

该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。

因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。

注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择“在新窗口中打开”时,子窗口便可以访问父窗口的Session。

URL地址重写

URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(Stringurl)实现URL地址重写,例如:

<td>

<ahref="<%=response.encodeURL("index.jsp?c=1&wd=Java")%>">

Homepage</a>

</td>

该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。重写后的输出可能是这样的:

<td>

<ahref="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=

1&wd=Java">Homepage</a>

</td>

即在文件名的后面,在URL参数的前面添加了字符串“;jsessionid=XXX”。其中XXX为Session的id。分析一下可以知道,增添的jsessionid字符串既不会影响请求的文件名,也不会影响提交的地址栏参数。用户单击这个链接的时候会把Session的id通过URL提交到服务器上,服务器通过解析URL地址获得Session的id。

如果是页面重定向(Redirection),URL地址重写可以这样写:

<%

if(“administrator”.equals(userName))

{

response.sendRedirect(response.encodeRedirectURL(“administrator.jsp”));

return;

}

%>

效果跟response.encodeURL(Stringurl)是一样的:如果客户端支持Cookie,生成原URL地址,如果不支持Cookie,传回重写后的带有jsessionid字符串的地址。

对于WAP程序,由于大部分的手机浏览器都不支持Cookie,WAP程序都会采用URL地址重写来跟踪用户会话。比如用友集团的移动商街等。

注意:TOMCAT判断客户端浏览器是否支持Cookie的依据是请求中是否含有Cookie。尽管客户端可能会支持Cookie,但是由于第一次请求时不会携带任何Cookie(因为并无任何Cookie可以携带),URL地址重写后的地址中仍然会带有jsessionid。当第二次访问时服务器已经在浏览器中写入Cookie了,因此URL地址重写后的地址中就不会带有jsessionid了。

二Cookie:保存在客户端的会话信息

Cookie是一小段可以嵌入到HTTP请求和响应中的数据,它在服务器端生成,并作为响应的一部分返回给用户。浏览器接收到包含Cookie的响应后,会把Cookie的内容用“键/值”对的形式写入到一个客户端专门存放Cookie的文本文件中。浏览器会把Cookie及随后生成的请求发送给相同的服务器,服务器可以再次读取Cookie中的内容,以此来保持状态。

Cookie的内容主要包括:名字、值、过期时间、路径和域。

其中的名字和值便是所谓的“键/值”对,这些就是需要在客户端保存的状态信息。

Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。

正常情况下,同一个一级域名下的两个二级域名如www.helloweenvsfei.com和images.helloweenvsfei.com也不能交互使用Cookie,因为二者的域名并不严格相同。如果想所有helloweenvsfei.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数,例如:

Cookiecookie=newCookie("time","20080808");//新建Cookie

cookie.setDomain(".helloweenvsfei.com");//设置域名

cookie.setPath("/");//设置路径

cookie.setMaxAge(Integer.MAX_VALUE);//设置有效期

response.addCookie(cookie);//输出到客户端

Cookie的安全属性

HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:

Cookiecookie=newCookie("time","20080808");//新建Cookie

cookie.setSecure(true);//设置安全属性

response.addCookie(cookie);//输出到客户端

提示:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。

java中把Cookie封装成了javax.servlet.http.Cookie类。每个Cookie都是该Cookie类的对象。服务器通过操作Cookie类对象对客户端Cookie进行操作。通过request.getCookie()获取客户端提交的所有Cookie(以Cookie[]数组形式返回),通过response.addCookie(Cookiecookie)向客户端设置Cookie。

相关推荐