Servlet Session
cookie技术交换会话ID
在响应中发送一个会话cookie:
HttpSession session = request.getSession();
从请求中获得会话ID并把它与现有会话匹配:
HttpSession session = request.getSession();
这里面的逻辑是:如果请求中包含了一个会话ID cookie,就找到与该Id匹配的会话;如果没有找到匹配的当前会话,则创建一个新的会话。
那么如何去判定会话是已经存在,还是刚刚创建的呢?答案是使用Session的isNew()方法,如果返回true,代表客户还没有使用这个会话做过响应,如果返回false,则代表不是新创建的会话。
会话其实指示针对与请求相关联的客户的,但除了使用请求对象获得会话以外,还可以从HttpSessionEvent得到HttpSession的引用。根据会话事件来定义的相应监听者接口里面要想获得HttpSession对象,需要通过event.getSession()
来获取。
对与浏览器禁用了cookie的情况,使用之前的request.getSession()
之后再调用Session的isNew()方法总会返回true,因为客户会忽略容器使用会话ID设置cookie的企图,且不会发回一个带有会话ID cookie首部的请求。这样,如果为了完成会话,交换会话ID,就必须采取另一种方法——URL重写。
URL重写交换会话ID
URL重写可以取得放在cookie中的会话ID,并把会话ID附加到访问应用的各个URL 的最后,即——URL+;jsessionid = 1234567,这样当用户点击这种链接时,到达容器的请求会在最后携带这个额外信息,容器会取得这部分,并用它来查询匹配的会话。
为了完成URL重写,必须对相应中的所有URL进行编码,这样URL重写才会奏效。实现方式是:response.encodeURL("/xxx")
。如果想要把请求重定向到另外一个URL,但是还是想使用一个会话,那么使用另外一个URL编码方法,response.encodeRedirectURL("/yyy")
URL重写是自动的,但是只有对URL进行编码了才能奏效。值得注意的是,URL编码一定是由响应来处理的。另外,如果应用依赖会话,必须使用动态生成的页面,静态页面是没办法完成自动的URL重写的。
cookie其他用处
cookie实际上就是在客户和服务器之间交换的一小段数据(一个name/value String对)。默认情况下,cookie同会话的寿命一样长,即一旦客户离开了浏览器,cookie就会消失。但是也可以让cookie的存活时间长一些,甚至在浏览器关闭之后还能持久保存。使用setMaxAge(int second)可以设置。
会话的迁移
对于分布式Web应用,每个VM中有一个ServletContext,每个VM上的每个servlet都有其自己的ServletConfig,但是对于每个Web应用上的一个给定的会话ID,只有一个HttpSession对象,而不论应用分布在多少个VM上。所以就涉及到会话的迁移了,迁移包括会话在当前VM上的钝化和在迁移VM上的激活。也只有在会话激活以后,才能访问会话的属性。