web会话管理,会话跟踪

通常,会话管理是通过服务器将 Session ID 作为一个 cookie 存储在用户的 Web 浏览器中来唯一标识每个用户会话。如果浏览器不支持 cookies,或者将浏览器设置为不接受 cookies,我们可以通过 URL 重写来实现会话管理。 

  实质上 URL 重写是通过向 URL 连接添加参数,并把 session ID 作为值包含在连接中。然而,为使这生效,你需要为你的 servlet 响应部分的每个连接添加 session ID 。 

   把 session ID 加到一个连接可以使用一对方法来简化:response.encodeURL() 使 URL 包含 session ID,如果你需要使用重定向,可以使用 response.encodeRedirectURL () 来对 URL 进行编码。 

  encodeURL () 及 encodeRedirectedURL () 方法首先判断 cookies 是否被浏览器支持;如果支持,则参数 URL 被原样返回,session ID 将通过 cookies 来维持。 

  来看下面的例子,两个 JSP 文件:hello1.jsp 和 hello2.jsp,及它们之间的影响。我们在 hello1.jsp 中简单的创建一个会话,并在 session 中存储一个对象实例。接着用户可以点击页面的连接到达 hello2.jsp。在 hello2.jsp 中,我们从 session 中获取原先放置的对象并显示它的内容。注意,我们在 hello1.jsp 中调用了 encodeURL() 方法来获得 hello2.jsp 的链接,使得在浏览器停用 cookies 的情况下,session ID 自动添加到 URL,hello2.jsp 仍能得到 session 对象。 

  首先在启用 cookies 的情况下运行。然后关闭对 cookie 的支持,重启浏览器,再运行一次。每次你都可以看到会话管理在起作用,并能在页之间传递信息。 

注意,如果你想让这个例子能在关闭了 cookies 的浏览器中工作,你的 JSP 引擎必须支持 URL 重写。 

 

 

一,会话跟踪(session tracking)技术
会话是客户端发送请求,服务器返回响应的连接时间段。
HTTP是无状态协议:每次都是单独连接,不能维持客户的上下文信息。
会话跟踪技术是用于维持客户端和服务器端通信信息的技术。

三种典型客户端会话跟踪解决方案:
  1,Cookie;
  2,URL重写;
  3,隐藏表单域;

二,会话Cookie
用于会话跟踪的Cookie叫做会话Cookie。Servlet规范中会话跟踪的cookie名字必须是JSESSIONID,保存在浏览器的内存中。区别于保存在外部存储设备的cookie。
对于存储在内存中的cookie,是不能被不同的浏览器进程共享,共享只能发生在同一个浏览器进程的不同窗口(对个窗口共享一个进程)中。对于存储在外部设备的cookie,可以多浏览器共享。


三,url重写
在浏览器不支持或禁用cookie的情况下,使用url重写代替cookie来跟踪用户会话。
每个页面都必须使用servlet或jsp动态生成(动态页面)。因为附加在URL上的sessionID是动态产生,所以对于静态页面的跳转,URL重写机制无能为力。
即使使用动态页面,如果用户离开了会话并且通过书签或链接再次回来,会话信息也会丢失,因为存储下来的链接含有错误的标识信息。

必须将所有发送到客户端的url进行编码,调用HttpServletResponse接口中的encodeURL()方法和 encodeRedirectURL()方法来实现。在调用sendRedirect()方法之前使用encodeRedirectURL()方法.

四,隐藏表单域
只能用于特定操作中。仅当每个页面都由表单提交而动态生成的时候,才可以使用隐藏表单域,用来存储相关会话信息。

五,servlet中的会话跟踪
javax.servlet.http.HttpSession接口是servlet提供会话跟踪解决方案。
HttpSession对象存放在服务器端,只是对cookie和url重写技术的封装应用,所以要求服务器支持cookie,可以全局切换到url重写。

1,访问与当前请求相关联的会话对象:getSession(boolean value)方法

  在会话过程中,web容器负责为客户端维护一个唯一的HttpSession对象。
  对于新会话,web容器创建使用实现了HttpSession接口的HttpSession对象封装当前请求会话的信息(散列表的方式存储)。
 
  使用HttpServletRequest的getSession()方法访问HttpSession对象。
   在后台,系统从cookie或URL重写附加的数据中提取出用户ID。以ID为key,遍历之前创建的HttpSession对象内建的散列表。
   如果找不到匹配的会话ID,系统重新创建一个新的会话。默认情况下(不禁用Cookie)还会创建一个名为JSESSIONID,值为唯一标识用户表示会话ID的输出cookie。 
  因为调用getSession()方法会影响到后面的响应,所以只能在发送任何文档内容到客户端之前调用getSession()方法。

  区别:getSession(boolean value)方法:如果系统没有找到与请求关联的会话ID,true表示返回新会话。false表示方法返回null。

2,访问和设置与会话相关联信息,维护会话的状态:HttpSession的getAttribute()方法和setAttribute()方法

  散列表:HttpSession对象内建数据结构,用于存储 当前请求会话的数据(会话的属性)。可以存储任意数量的key-value对。
  使用HttpSession的getAttribute()方法和setAttribute(String key,Object value)方法读取和设置当前请求会话数据(即对散列表的操作),维护会话的状态。
  setAttribute方法会替换任何之前的属性。如果不想被替换,则需要在设置之前使用removeArrtibute(String key)方法移除该属性。
 
  setAttribute方法会触发所有实现了HttpSessionBindingListener接口的valueBound方法,做一些初始化状态的操作。
  removeArrtibute方法会触发所有实现了HttpSessionBindingListener接口的valueUnbound方法,做一些消除状态的操作。

  对于分布式WEB应用程序,将web应用程序标记为可分布式执行,系统需要能够将会话对象在机器之间传递,这时需要将会话的属性实现Serializable接口。

3,废弃会话数据
  只移除自己编写的的servlet创建的数据:removeArrtibute(String key)方法
  (web应用程序中删除)删除整个会话:invalidate()方法,可以用该方法注销用户。
  (Web服务器中删除)将用户从系统中注销并且删除所有与该会话关联的会话:logout()方法。一定要与其他web应用程序协调loggout命令的使用。
 
4,会话超时时间间隔
  getMaxInactiveInterval()方法和setMaxInactiveInterval()方法读取和设置在没有访问的情况下,会话保存的最长时间。秒为单位。负数表示会话从不超时。超时由服务器来维护。

5,会话最后次被客户端访问的时间:getLastAccessedTime()方法
  可以用来确定客户端在二次请求之间会话的非活动时间。

6,获取会话被创建的时间:getCreationTime()方法 返回long类型数据

7,返回分配给session的唯一标识ID,为字符串。getId()方法

六,浏览器会话与服务器会话
浏览器会话
  默认情况下,会话跟踪基于存储在浏览器内存中的cookie,区别于存储在外围存储设备上的cookie。
  需要servlet显示的读取JSESSION cookie,设置最大时效和路径并添加到客户端,否则退出浏览器就会中断会话。
服务器会话
  服务器需要将会话保存在内存中,在会话处于非活动状态超过设定的间隔(会话超时)就移除会话。

七,对绑定到session中的对象(属性)初始化和消除状态。HttpSessionBindingListener监听器接口和HttpSessionBindingEvent事件类。

Servlet容器通过实现HttpSessionBindingListener监听器接口的监听器来监听HttpSessionBindingEvent事件。

HttpSessionBindingListener监听器接口方法:
1,valueBound(HttpSessionBindingEvent event):对象被绑定到session中时该方法通知对象。做初始化操作。
2,valueUnbound(HttpSessionBindingEvent event): 对象被移除出session时该方法通知对象。做消除状态操作。

HttpSessionBindingEvent事件方法:
1,getName():获取触发事件的属性的名字。
2,getValue():获取触发事件的属性的值。
3,getSession():返回Session对象。


八,在 Java Servlet API中有关的监听器接口。

与Session相关的监听器接口
javax.servlet.http.HttpSessionActivationListener:如果绑定到Session中,当Session被钝化或激活时,Servlet容器将通知该对象。
javax.servlet.http.HttpSessionAttributeListener:如果想要在Session中的属性列表发生改变时得到通知,可以实现这个接口。
javax.servlet.http.HttpSessionListener:如果需要在Session创建后或者Session无效前得到通知,可以实现这个接口,实现该接口的类必须在web应用程序的部署描述符中进行配置。

与Servlet上下文有关的监听器接口:
javax.servlet.ServletContextAttributeListener:在Servlet上下文中的属性列表发生改变时得到通知,可以实现这个接口,实现该接口的类必须在web应用程序的部署描述符中进行配置。
javax.servlet.ServletContextListener:如果需要在Servlet上下文对象初始化时或被销毁的时候得到通知,可以实现这个接口,实现该接口的类必须在web应用程序的部署描述符中进行配置。

与请求相关的监听器接口:servlet2.4规范定义
javax.servlet.ServletRequestAttributeListener:Servlet请求对象中的属性发生改变时得到通知。
javax.servlet.ServletRequestListener:请求对象初始化或者被销毁时得到通知。
posted @ 2014-04-01 18:54  奋斗中的毛毛虫  Views(276)  Comments(0)    收藏  举报