首页 理论教育JavaWeb应用开发:有效的会话跟踪技术

JavaWeb应用开发:有效的会话跟踪技术

【摘要】:Cookie 以键/值对的方式记录会话跟踪的内容,服务器利用响应报头Set-Cookie 来发送Cookie 信息。这样,通过为不同的用户发送不同的Cookie,就可以实现每个用户的会话跟踪。表3.1Cookie 类常用的方法例3.4:Cookie 使用示例。创建一个Servlet 用于删除Cookie,该Servlet 处理GET 请求的代码如下:Cookie 主要是用于会话跟踪的一种技术,也是会话跟踪技术中最常用的一种。在Servlet 规范中,用于会话跟踪的Cookie 的名字必须是JSESSIONID。

1.Cookie

Cookie,中文译为小甜饼,由Netscape 公司发明,是最常用的跟踪用户会话的方式。Cookie 是一种由服务器发送给客户的一小段文本,存储在客户端浏览器的内存中或硬盘上,在客户随后对该服务器的请求中发回它。

Cookie 以键/值对的方式记录会话跟踪的内容,服务器利用响应报头Set-Cookie 来发送Cookie 信息。例如:

上面这个响应报头发送了一个名为uid,值为zhangsan 的Cookie,Cookie 的生存时间为3 600 s,在baidu.com 域的/bbs 路径下有效。在3 600 s 之后,浏览器应该丢弃这个Cookie。

当浏览器收到上面这个响应报头后,可以选择拒绝或接受这个Cookie。如果浏览器接受了这个Cookie,当浏览器下一次发送请求给在baidu.com 域的/bbs 路径下的资源时,同时也会发送下面的请求报头:

服务器从请求报头中得到Cookie,然后通过标识取出在服务器中存储的zhangsan 的状态信息。这样,通过为不同的用户发送不同的Cookie,就可以实现每个用户的会话跟踪。

以上是通过HTTP 报头的形式向客户端写入和从客户端读取Cookie,显然通过这种形式是不方便的。与请求和响应一样,Servlet API 为使用Cookie 也提供了一个专有的操作类:javax.servlet.http.Cookie。

Cookie 类主要有以下的方法,见表3.1。

表3.1 Cookie 类常用的方法

例3.4:Cookie 使用示例。

在ch04 项目中建立一个Servlet,命名为“UseCookie”。在UseCookie 的GET 请求中,首先获得用户请求中的所有Cookie,并显示出来;若请求中没有Cookie,则向客户端写入一个Cookie。UseCookie.java 代码如下:

从上述代码中可以看出获取Cookie 使用的是request 对象的getCookies()方法,该方法返回的是一个Cookie 数组。Cookie 类提供了构造方法创建Cookie 对象,构造方法第一个参数是Cookie 名称(即键/值对中的键),第二个参数是值(即键/值对中的值)。可以创建多个Cookie 对象,但是每个Cookie 对象都必须要有独一无二的名称,如果创建了两个同名的Cookie 对象,后保存的那一个Cookie 对象的值就会覆盖前一个Cookie 对象的值。response 对象提供了addCookie()方法将Cookie 写入客户端。

重启Tomcat 服务器,打开IE 浏览器,使用以下地址访问UseCookie。

第一次运行效果如图3.15 所示,没有获取到任何Cookie。

图3.15 例3.3 运行效果(没有Cookie 时)

向客户端写入一个Cookie:userName=zhangsan,并单击“重新查看”链接,效果如图3.16 所示,显示出了刚写入的Cookie。

图3.16 例3.3 运行效果(有Cookie 时)(www.chuimin.cn)

有时希望删除Cookie,然而javax.servlet.http.Cookie 类并没有提供删除Cookie的方法,response 对象也没有此方法,那怎么删除呢?

其实很简单,就是使用Cookie 对象的setMaxAge()方法。该方法有一个参数,提供一个整数表示Cookie 的最大保存时间,单位为s。如果将最大保存时间设置为0,则表明指示浏览器立即删除此Cookie。其实setMaxAge()是可选的,并不一定要用此方法设置Cookie 的最大保存时间。若创建Cookie 时未指定最大保存时间,那么最大保存时间将默认为-1,指关闭浏览器窗口时此Cookie 就失效。

在例3.4 中,还提供了一个“删除此Cookie”的超级链接,现在就来实现此功能。创建一个Servlet 用于删除Cookie,该Servlet 处理GET 请求的代码如下:

Cookie 主要是用于会话跟踪的一种技术,也是会话跟踪技术中最常用的一种。在Servlet 规范中,用于会话跟踪的Cookie 的名字必须是JSESSIONID。例如以下HTTP报头片段:

因为Cookie 是在响应报头和请求报头中被传送的,不与传送的内容混淆在一起,所以Cookie 的使用对于用户来说是透明的。然而也正是因为Cookie 对用户是透明的,加上Cookie 持久性高,可以长时间的追踪用户(Cookie 可以保存在用户机器的硬盘上),了解用户上网的习惯,而用户在网上的一举一动,就有可能成为某些网站或厂商牟利的机会,这就造成了一些隐私权和安全性方面的问题。于是有些用户在使用浏览器时,会选择禁用Cookie。

图3.17 设置阻止所有Cookie

例如在IE 的“Internet 选项”中把“隐私”选项的内容设置为“阻止所有Cookie”,如图3.17 所示。客户端浏览器设置为阻止所有Cookie 之后,Web 服务器就无法利用Cookie,这样的话,Web 服务器就无法利用Cookie 来跟踪用户的会话了,要解决这个问题,就要用到URL 重写机制。

2.URL 重写

通常,会话管理是通过服务器将Session ID 作为一个Cookie 存储在用户的Web 浏览器中来唯一标识每个用户的会话。当客户端不接受Cookie 的时候,可以使用URL 重写的机制来跟踪用户的会话。URL 重写就是在URL 中附加标识客户的Session ID,Servlet 容器解释URL,取出Session ID,根据Session ID 将请求与特定的Session关联。

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

若每个URL 自己手动重写(即手动向URL 中添加jsessionid 参数),这比较麻烦。可以使用HttpServletResponse 接口中的encodeURL()和encodeRedirectURL()方法来实现。其中encodeRedirectURL()方法主要在sendRedirect()方法之前使用,用于编码重定向的URL。

encodeURL()和encodeRedirectURL()方法只有在客户端禁用Cookie,并且存在会话的情况下,执行时才会重写URL,否则将返回没有任何变化的URL。

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

对于使用URL 重写技术进行会话跟踪将在后面介绍Session 时一并举例。

3.隐藏表单域

另一种保持客户端会话的技术叫隐藏表单域(或称为隐藏表单字段)。也就是在表单中添加一个隐藏字段,以便在表单提交时能够把Session ID 传递回服务器。例如以下为传递给客户端的表单:

隐藏字段的name 属性值必须为“jsessionid”,因为这种方式相当于代替了URL 重写中的jsessionid 参数,所以名称要一致,服务器端才能识别。