Servlet--会话跟踪

HTTP是有一种无状态的协议,形象的说,就是大家在交流(发送/处理请求)的时候,无法识别谁在说话。
本文的前半部分会介绍基于CGI开发者使用的传统会话跟踪技术:用户鉴别、隐藏表单字段、URL重写和持续性cookie,后半段介绍Servlet API中对会话跟踪的内置支持。
本章主要介绍单服务器的状态,在《企业服务和J2EE》中将介绍多服务处理共享会话状态。

用户鉴别

在客户登陆进入后,servlet可以使用getRemoteUser()取得用户名。
我们可以使用用户名来跟踪客户端会话。用户登陆后,浏览器记住用户名并且在浏览新网页时重发名称和密码。serlvet通过用户名对用户进行鉴别并跟踪会话。举个简单的例子,一个用户在他的购物车上增加一项,这个信息就被记录(比如数据库中),以后用户结账的时候,另一个servlet调用数据库中的信息就可以了。
这个方法最大优点是容易实现。
最大的缺点是需要用户登陆账号,比较麻烦。另一个缺点是HTTP的基本鉴别没有提供注销技术,用户必须关闭浏览器以注销(当然我们现在都有登出操作了)。最后一个问题是,用户不能对一个网点进行多个会话。我们需要支持匿名会话跟踪和注销的鉴别技术。

隐藏的表单字段

支持匿名会话跟踪的一个方法是使用隐藏的表单字段。顾名思义,就是用HTML表当上不在客户端显示的字段,它们在表单提交后被返回到服务器。可以像这样使用它:

<FORM ACTION="/servlet/MovieFinder" METHOD="POST">
...
<INPUT TYPE=hidden NAME="zip" VALUE="94040">
<INPUT TYPE=hidden NAME="level" VALUE="expert">
...
</FORM>

在某种意义上,隐藏的表单字段为表单定义了一个常数常量。对于一个servlet而言,隐藏字段和可见字段没有区别。
隐藏表单字段的优点在于普遍性和对匿名的支持。隐藏字段被所有流行的浏览器支持,它们不需要服务器特殊服务,并且它们可以用于未注册和登陆的客户端。该技术的主要缺点是会话只能存在于动态生成的表单中。会话不能在静态文本、发送的文档、书签文档和在浏览器关闭时存在。

URL重写

URL重写是支持匿名会话跟踪的另一个方法。使用URL重写技术,每个可能被用户点击的本地URL都会被动态修改,或重写以包含附加信息。附加信息可能是附加路径信息、附加参数或定制的服务器端指定的URL变换形式。在URL重写中,附加信息通常是一个独特的会话ID。例如:

http://server:port/servlet/Rewritten                 original
http://server:port/servlet/Rewritten/123             extra path information
http://server:port/servlet/Rewritten?sessionid=123   added parameter
http://server:port/servlet/Rewritten;jsessionid=123  custom change

持续性cookie

cookie是一些由服务器发向浏览器并且还能由浏览器读回的信息。当浏览器收到一个cookie,就将这个cookie保存起来,并当每次它访问该服务器的网页时,都将这个cookie发送回服务器。因为一个cookie的值可以唯一确定一个客户端,所以cookie常用于会话跟踪。

使用cookie

servlet API提供了javax.servlet.http.Cookie类来运行cookie。cookie的HTTP首部有关细节处理由Servlet API进行。我们可以用Cookie()构造函数来生成一个cookie:

 public Cookie(String name, String value)

通过在请求的防止中AddCookie()方法向客户端发送一个cookie,并且能用AddCookie()继续添加。浏览器对每个网站最多接受20个cookie,每个用户最多300个,并且浏览器将每个cookie设置在4096字节内。

 public void HttpServletResponse.addCookie(Cookie cookie)

会话跟踪API(Session)

Servlet API提供了一些方法和类专门处理短期的会话跟踪。

会话跟踪基础

网站的每个用户都和javax.servlet.http.HttpSession对象有关,servlet使用这个对象来记录和检索每个用户的信息。

    public HttpSession HttpServletRequest.getSession(boolean create)

会话的生命周期

会话并不是一直延续下去的。会话在非活动固定时间(Tomcat默认30分钟)后自动关闭,或者由servlet关闭。

设定会话超时

理论上讲,会话将在用户关闭浏览器时失效,连接到其他网站或用户离开。但是,服务器无法检测到这些事件。因此,服务器在会话不活动一段时间后就假设用户已经离开,不再需要保持会话了。
默认的会话超时可使用web.xml来自定义。

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
    "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

<web-app>
    <!-- ..... -->
    <session-config>
        <session-timeout>
            60 <!-- minutes -->
        </session-timeout>
    </session-config>
</web-app>

或者对HttpSession对象设置一个超时时间

    public void HttpSession.setMaxInactiveInterval(int secs)

给出一个负值表示不会超时。

会话如何工作

当用户第一次访问一个Web应用程序,用户被分配一个HttpSession对象和一个唯一的会话ID。这个会话ID代表用户并用于和后边请求中的HttpSession相匹配。有些服务器使用一个会话ID,每个应用程序将这个ID映射到一个不同的HttpSession实例。有些服务器则会为每个Web应用程序分配一个会话ID,用来预防恶意入侵者模拟用户来破坏Web应用程序。
在后台,会话ID通常保存在客户端一个叫做JSESSIONID的cookie中。

会话绑定事件

一些对象希望在被绑定在会话和从会话中释放时都能有所动作。例如,一个数据库连接可能在绑定在会话上时开始一个传输,并在被释放时结束传输。任何实现了javax.servlet.http.HttpSessionBindingListener接口都从会话绑定或释放时被通知。这个接口实现了两个方法,valueBound()和valueUnbound()。

发布了29 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/u014730658/article/details/78823291