session是web中在服务器端保存用户状态的一种方式,http协议本身属于无状态协议。服务器端维护session用到了俩种方式:
1. 将sessionid保存在cookie中,在浏览器支持cookie的情况下,服务器端会写jsessionid到客户端的cookie中,服务器端也维护一个session池,并且这个池有时间限制,也可以配置实效时间。这样客户端在每个请求中带上服务器端写入的sessionid,服务器端就能匹配到相应的session了,从而达到了维护客户端状态的目的。
2. 如果客户端浏览器不支持cookie,就采取url从写的技术,用户在请求服务端时,会再用户请求的url后边加上;jsessionid=xxx,这样的参数,就可以达到客户端存储cookie的效果。这就是浏览器不支持cookie时,通过客户端记录sessionid编号来维护客户端状态。
cookie的内容:
包含: 名称、值、过期时间、存储路径和域。
域是指一个网站或一个B/S的应用。
路径是指域名后URL的路径。
域和路径在一起构成了cookie的作用范围。
子域可以访问父域的cookie内容,而父域不可以访问子域的cookie内容。
没有过期时间的cookie:
不设置过期时间,则表示这个cookie的生命周期为浏览器的会话时间,只要关闭浏览器窗口,cookie就消失了,这种生命周期为浏览器会话的cookie称之为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存中。
设置了过期时间的cookie:
设置了cookie的过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效,一直到超过有效时间。
/**
* 写入Cookie
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void writeCokie(HttpServletRequest request,HttpServletResponse response,String name,
String value,int days)throws ServletException, IOException {
int day = 24 * 60 * 60;
Cookie cookie = new Cookie(name, value);
cookie.setMaxAge(days * day);
response.addCookie(cookie);
}
/**
* 根据名称读取Cookie
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected String readCokie(HttpServletRequest request,HttpServletResponse response,String name)
throws ServletException, IOException {
String value = null;
if(StrUtil.isNotNull(name)){
Cookie cookies[] = request.getCookies();
if(cookies!=null && cookies.length >=2){
for(int i=0;i
Cookie cookie = cookies[i];
if(name.equals(cookie.getName())){
value = cookie.getValue();
}
}
}
}
return value;
}
/**
* 清空cookie
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void clearCokie(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
cookie机制和session机制的区别:
cookie机制采用的是在客户端保持状态的方案。
而session机制采用的是在服务器端保持状态的方案。
服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来 达到保存标识的目的。
会话cookie和持久cookie的区别
如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就 消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有 效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie ,不同的浏览器有不同的处理方式。
session的机制
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保 存信息。
程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了 一个session标识-称为session id,如果已经包含一个session id则说明以前已经为此客户创建过session,服务器就按照 session id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应 的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。
如果客户请求不包含session id,则为此客户创建一个session并且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。
保存session id的几种方式
保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给 服务器。
cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把session id传递回服务 器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路 径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能 请求的路径后面都包含这个session id。
另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时 能够把session id传递回服务器。
session什么时候被创建
一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet) 调用HttpServletRequest.getSession(true)这样的语句时才会被创建。
session何时被删除
程序调用HttpSession.invalidate()。
距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间。
服务器进程被停止。
再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的 session对象失效。
URL重写的缺点
对所有的URL使用URL重写,包括超链接,form的action,和重定向的URL。每个引用你的站点的URL, 以及那些返回给用户的URL(即使通过间接手段,比如服务器重定向中的Location字段)都要添加额外的信息。
这意味着在你的站点上不能有任何静态的HTML页面(至少静态页面中不能有任何链接到站点动态页面 的链接)。因此,每个页面都必须使用servlet或JSP动态生成。即使所有的页面都动态生成,如果用户离开了会话并通过书签 或链接再次回来,会话的信息都会丢失,因为存储下来的链接含有错误的标识信息-该URL后面的SESSION ID已经过期了 。