会话跟踪技术

1 会话跟踪技术

在Servlet规范中,有以下三种机制用于会话跟踪:

1) SSL(安全套接字层)会话:

  一种加密技术,主要原理是采用SSL的服务器和客户端之间产生会话密钥,建立一种加密的连接会话。

2) Cookies:

  是最常用的跟踪用户会话的方式,Cookie是一种由服务器发送给客户的片段信息,存储在客户端浏览器的内存或硬盘上,客户端在发起请求时携带此信息最为用户的唯一标识。

Cookie以键值对的方式记录会话跟踪的内容,服务器利用响应报头Set-Cookie来发送Cookie信息。在RFC2109中定义的Set-Cookie响应报头的格式为:

Set-Cookie: NAME=VALUE ; Comment=value ; Domain=value ; Max-Age=value ; Path=value ; Secure ; Version=1*DIGIT

NAME是Cookie的名字,VALUE是Cookie的值。NAME=VALUE 属性-值对必须首先出现,在此之后的属性-值对可以任何顺序出现。在Servlet规范中,用于会话跟踪的Cookie的名字必须是JSESSIONID。

Comment属性可选,因为Cookie可能包含关于用户的私有信息,这个属性允许服务器说明这个Cookie的使用,用户可以检查这个信息,然后决定是否加入或者继续会话。

Domain是可选属性,用于指定Cookie在哪一个域中有效,所指定的域必须以点号(.)开始。

Max-Age属性是可选的,用于定义Cookie的生存时间,以秒为单位,如果超过了这个时间,客户端应该丢弃这个Cookie,当然如果指定的秒数为0,表示立即丢弃这个Cookie,即客户端不保存此Cookie。

Path属性是可选的,用于指定这个Cookie在哪一个URL子集下有效。

Secure属性也是可选,它没有值,用于指示浏览器使用安全的方式与服务器交互。

Version属性是必需的,它的值是一个十进制的整数,标识Cookie依照的状态管理规范的版本。

举例:

Set-Cookie: uid=zhen; Domain=.hzw.org ; Max-Age=3600 ; Path=/zwbg; Version=1

以上这个响应报头发送了一个名为uid,值为zhen的Cookie,Cookie的存活时间是3600秒,在hzw.org域的/zwbg路径下有效,在3600秒后,浏览器会丢弃这个Cookie。

在浏览器收到这个响应报头后,可以选择拒绝或者接受这个Cookie,如果浏览器接受这个Cookie,当浏览器下一次发送请求给http://www.hzw.org/zwbg/路径下的资源时,同时也会发送下面的请求报头: Cookie:uid=zhen  ,服务器从请求报头中得到Cookie,然后通过标识取出在服务器中存储的zhen的状态信息,通过为不同的用户发送不同的Cookie,就可以实现每个用户的会话跟踪。

因为Cookie是在响应报头和请求报头中被传送的,不与传送的内容混淆,所以Cookie的使用对于用户来说是透明的。然而正是因为Cookie对用户是透明的,加上Cookie的持久性高,可以长时间的追踪用户(Cookie可以保存在用户的硬盘里),了解用户的上网习惯,造成一些隐私权和安全方面的问题,于是有些用户在使用浏览器时会禁用Cookie,这样的话,web服务器就不能利用Cookie来跟踪用户的会话了,要解决这个问题,可以使用下面要讲的URL重写机制。

3)URL重写

  当客户端不接受Cookie的时候,可以使用URL重写的机制来跟踪用户的会话。

URL重写就是在URL中附加标识客户的sessionID,Servlet容器解释URL,取出SessionID,根据SessionID就可以将请求和特定的Session关联。

sessionID被编码为URL字符串中的路径参数,在Servlet规范中,这个参数的名字必须是jsessionid,下面是一个包含了编码后的路径信息的URL的例子:

http://www.hzw.org/zwbg/index.jsp;jsessionid=1234

还可以在后面加上查询字符串,完整的URL为:

http://www.hzw.org/zwbg/index.jsp;jsessionid=1234?name=zhen&age=18

服务器将sessionID作为URL的一部分发送给客户端,客户端在请求URL中再传回来,这样服务器就可以跟踪用户的会话了。

要跟踪客户端的会话,就必需将所有发往客户端的URL进行编码,这可以通过调用HttpServletResponse接口中的encodeURL()方法和encodeRedirectURL()方法来实现。其中encodeRedirectURL()方法主要在sendRedirec()方法调用之前使用,用于编码重定向的URL。


 

2 Servlet API的会话跟踪

在java Servlet API中,javax.servlet.http.HttpSession接口封装了Session的概念,Servlet容器提供了这个接口的实现。当请求一个会话时,Servlet容器就创建一个HttpSession对象,有了这个对象之后,就可以利用这个对象保存客户的状态信息。

比如,购物车,Servlet容器为HttpSession对象分配一个唯一的SessionID,将其作为Cookie(或者作为URL的一部分,利用URL重写机制)发送给浏览器,浏览器在内存中保存这个Cookie。当客户再次发送HTTP请求时,浏览器将Cookie随请求一起发送,Servlet容器从请求对象中获取SessionID,然后根据SessionID找到对应的HttpSession对象,从而得到客户的状态信息。

整个会话过程对于开发和用户来说都是透明的(由Servlet容器完成),开发人员只需得到HttpSession对象,然后调用这个对象的setAttribute()或者getAttribute()方法来保存获取读取客户的状态信息。整个会话跟踪过程如图:


 1)HttpSession接口:

方法:

这四个方法是在HttpSession对象中读取、移除和设置属性,利用这些方法,可以在Session中维护客户的状态信息

public abstract Object getAttribute(String s);

public abstract Enumeration getAttributeNames();

public abstract void setAttribute(String s, Object obj);

public abstract void removeAttribute(String s);

 

public abstract long getCreationTime(); 返回Session的创建时间,这个时间是从1970年1月1日00:00:00GMT以来的毫秒数

public abstract String getId(); 返回一个字符串,其中包含了分配给Session的唯一标识符,这个标识符是由Servlet容器分配的,与具体的实现没关

public abstract long getLastAccessedTime(); 返回客户端最后一次发送与Session相关请求的时间,这个时间是从1970年1月1日00:00:00GMT以来的毫秒数。这个方法可以用来确定客户端在两次请求之间会话的非活动时间。

 

public abstract void setMaxInactiveInterval(int i);设置在Session失效之前,客户端的两个连续请求之间的最大时间间隔,如果设置一个负值,表示session永远不会失效,web应用程序可以使用该方法来设置Session的超时时间间隔。

public abstract int getMaxInactiveInterval();返回以毫秒为单位的最大的时间间隔。这个时间间隔值是Servlet容器在客户的两次连续请求之间保持Session打开的最大时间间隔,超过这个时间间隔,Servlet容器就使Session失效。

 

public abstract void invalidate();

  这个方法使会话失效,例如在网上书店购买完图书后,就可以选择退出登录,服务器端的web应用程序可以调用这个方法是Session失效,从而让用户不再与这个Session关联

public abstract boolean isNew();

  如果客户端还不知道这个Session或者客户端没有选择加入Session,那么这个方法将返回true。例如服务器使用基于Cookie的Session,而客户端禁用了Cookie,那么对于每一个请求,Session都是新的。

  要得到一个Session对象,可以调用HttpServletRequest接口的getSession()方法:

  1)public HttpSession getSession();该方法返回与此请求相关联的Session,如果没有给用户分配Session,则会创建一个新的Session

  2)public HttpSession getSession(boolean create)该方法返回与请求相关联的Session,如果没有给客户分配Session,而create参数为true,则会创建一个新的Session,如果create参数为false,而此请求没有一个有效的HttpSession,则返回null


public abstract ServletContext getServletContext();

  返回Session所属的ServletContext对象


 

posted @ 2016-10-10 09:54  zwbg  阅读(3770)  评论(0编辑  收藏  举报