servlet容器为每一个HttpSession对象分配一个唯一标志符sessionID。
会话流程:
1.一个浏览器第一次访问支持session的网页,查找有没有sessionId的cookie。没有就创建一个HttpSession对象,分配一个 SessionID,写到cookie中保存在客户端。
2.不是第一次访问,发现有了sessionID的cookie,所以就不会创建新的HttpSession对象。然后就去查找sessionID对应的HttpSession对象。进行操作。
3.重复第2步,直到session销毁。
Jsp页面默认情况是支持session的。也可以关闭
<%@ page session="false"%>//加上这一句就不支持session,也就不会创建Httpsession对象。
HttpSession接口方法
getId()//返回sessionid
invalidate()//销毁httpsession对象
setAttribute(name,value)
getAttribute(name)
getAttributeNames()//得到所有的属性
removeAttribute(name)
isNew()//是不是新创建的
setMaxInactiveInterval(int interval)//设置不活动状态的最长时间,超过时间销毁对象,设置负数表示永远不过期
getMaxInactiveInterval()
getServletContext()
以下几种情况会话会被销毁。
1.浏览器进程终止。要等到会话过期才会销毁。
2.服务器执行HttpSession对象的invalidate()方法。
3.会话过期。tomcat默认1800秒。可以设置不过期。
tomcat关闭不会销毁会话,而是持久化到永久花的存储设备中。重启后重新加载会话。可以设置tomcat属性关闭这种情况。
Jsp默认支持会话,所以有隐含对象session来直接访问HttpSession。HttpServlet默认不支持会话。可以通过HttpServletRequest来得到HttpServlet对象。
getSession():使得当前HttpServlet支持会话。如果没有HttpSession对象就创建一个。有就返回原来的对象。
getSession(boolean create)为true,跟getSession()一样。false会话不存在就返回null,存在就返回原来的对象。
支持会话,浏览器不支持cookie时可以用HttpServletResponse.encodeURL(string url)来重写url。就是在url后面加sessionid来判断是不是用一用户,其他情况直接使用url。
会话的持久化
某些情况下,httpSession对象会被持久化到永久化的存储设备中(数据库或硬盘)。用到的时候再加载到内存。使用的是Java对象序列化技术。
持久化的两个好处:
1.节省内存空间。把不活动的HttpServlet对象保存到存储设备中,可以提高内存资源的利用率。
2.服务器重启后能恢复会话。
会话的两个状态:
运行时状态:对象处于内存中,分为不活动状态和活动状态。
持久化状态:对象位于存储设备中。
会话从运行时状态改为持久化状态叫做搁置或者持久化。一下几种情况会被搁置。
1.服务器终止。
2.会话处于不活动状态太久了。超过了限定值。
3.web应用处于活动状态的会话太多超过了限定值,部分会话会被搁置
会话从持久化到运行时状态叫做激活或者加载
1.服务器重启。
2.一个会话的客户端发送HTTP请求。
会话的持久化是依靠servlet容器的,tomcat的会话管理器有两种。
1.标准会话管理器StandardManager
这是默认的标准会话管理器,实现机制为:服务器终止,被终止的应用会被持久化。重启是会激活对象。
2.持久化会话管理器
更灵活,功能:
1.服务器关闭,持久化对象,重启记载对象。
2.具有容错功能:及时备份对象(持久化)。服务器意外关闭可以恢复对象。
3.可以控制内存会话数目,将部分会话持久化。
会话的监听
在servlet api定义了4个监听器接口
1.HttpSessionListener:监听创建和销毁会话的事件。
sessionCreate(HttpSessionEvent event)创建会话后,调用。
sessionDestroyed(HttpSessionEvent event)销毁会话之前,调用。
2.HttpServletAttributeListener:监听加入属性,替换属性,删除属性的事件。
attributeAdded(HttpSessionBindingEvent event):加入属性时,调用。
attributeRemoved(HttpSessionBindingEvent event):删除属性时,调用。
attributeReplaced(HttpSessionBindingEvent event):替换属性时,调用。
3.HttpSessionBindingListener监听会话和属性绑定或解除绑定的事件。
valueBound(HttpSessionBindingEvent event)绑定后执行
valueUnbound(HttpSessionBindingEvent event)解除绑定前执行
4.HttpSessionActivationListener:监听激活或者搁置的事件。
sessionDidActivate(HttpSessionEvent event)激活后 调用
sessionWillPassivate(HttpSessionEvent event)搁置之前调用
3和4只要一个类实现接口就行了,session.setAttribute("name",实现类)就会触发绑定事件。
用HttpSessionListener统计在线人数
每创建一个session就是数量加1,销毁就数量减一。把数量保存在servletContext中(event.getSession().getServletContext())。这个接口的两个方法干好可以用到。不过要在web.xml里面配置监听器。这个统计的是HttpSession对象的数量,其实不是真正的在线人数。也无法统计在线人数的具体名单。
用HttpSessionBindingListener统计在线人数
用一个类实现这个接口,然后绑定的时候把名字传到一个公共的类中(这个类有一个static final 自己类=new 自己类这样就可以确保这个类不会重复创建,然后用一个方法返回这个类对象),就可以从list中取到用户的名字。统计的也是session对象数量不过可以绑定属性。