Servlet第四篇-Session生命周期及监听器

前言

此篇需要结合前面两篇: [Servlet第一篇-Web基础] 以及[Servlet第三篇-Cookie和Session] 进行理解。没有看过的旁友,穿越一波。

这个web知识很重要滴!!(敲黑板)

这一篇文章根据监听器的灵感而来,发现由此学习session是个不错的选择,所以开始吧!!!


监听器

监听器listener共八个监听器,根据按照监听对象可以分为三类:

监听ServletContext事件的

  • ServletContextListener 作用:监听全局作用域 application 的生命周期(服务器启动就创建,服务器关闭则销毁)
  • ServletContextAttributeListener: 作用:监听 ServletContext 域中属性变化的

监听 HttpSession事件的

  • HttpSessionlistener 作用:监听Httpsession的生命周期:如session的创建、超时、或被手动设置失效等等
  • HttpSessionattributelistener 作用:监听所有对象在Httpsession城中属性变化(发生增删改操作)

下面两个监听器比较特殊:

①不需要在xml注册、需要实现一个“序列号接口” Serializable

② 针对某个对象进行操作的,就是要对哪个对象进行监听,就在哪个对象上实现接口

  • HttpSessionActivitionListener 作用:监听某个对象随着Httpsession活化钝化的过程;
  • HttpSessionBindingListener: 作用:监听某个对象保存(绑定)到 session中和从session中移除(解绑)

监听ServletRequest事件的

  • ServletRequestListener 作用:监听 request对象的生命周期(当有一个请求进来时创建新的request,并保存请求的 详细信息,当这个请求完成时销毁request对象)
  • ServletRequestAttributeListener 作用:监听 request 域中属性变化的

当以上内容监听到相对应的事件时,就会触发相对应的方法。


什么意思呢? 举个HttpSession监听器的例子来说:

①第一步,你想使用监听器功能,就需要实现HttpSessionListener接口,这时候,应该继承两个API方法(sessionCreated和sessionDestroyed)

1
2
3
4
5
6
7
8
9
10
11
public class Listener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("会话创建"+se.getSession().getId());
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("会话销毁");
}
}

②第二步,API中的方法就是对应事件发生时你想要做出的动作。


③第三步,要想监听器生效,需要在xml中配置(路径应该写全类名):

1
2
3
<listener>
<listener-class>org.student.servlet.Listener</listener-class>
</listener>

④ 最后,当服务器生成Session会话时,我们编写的Listener监听器就会监听到。



Session生命周期问题

就着上面的话题,我们编写了一个HttpSessionListener的监听器,我们来研究一下session。这也是我们今天的主要内容。请跟着我的思路,来探寻这个神秘的会话机制。


一、首先,我们启动了服务器。这时候,控制台打印是这样的:(发现什么都没有打印)

这时候,我们编写一个session.jsp页面,然后去浏览器上去访问这个资源(内容特别简单,就是个a标签),同时,打开控制台进行抓包:

1
2
3
4
5
6
7
8
9
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="">hello</a>
</body>
</html>

二、让我们看看抓包信息:

分析抓包我们得到以下内容:

① 浏览器发送的请求中并没有携带cookie ;②服务器响应时有个字段:set-cookie

然后,我们去查看浏览器缓存中的cookie内容,发现生成以下字段


三、观察打印台输出:

结论:观察后发现,这cookie的值是一样的。

有一点奇怪现象引起了我们的思考:

为什么访问session.jsp页面就触发了会话生成?我们也没有做什么事情啊(里面就一个a标签)。回想我们上一章讲的,这jsp页面中,包含着内置对象(不需要实例化就可以创建),也就是说,服务器帮你请求生成好了这些对象,当然有会话之类的资源创建生成啦!


四、会话销毁

当会话的生效时间(默认5分钟)到期之后,会话删除;

另一种session的老化是由我们手动设置老化时间。


五、再一次刷新页面(重新发起请求):

发起请求时,浏览器携带着之前记录的cookie。我们知道,浏览器拿到cookie之后会在session中匹配寻找(对应的session已经老化),所以服务器又通过set-cookie分配新的cookie值。这时候,浏览器的cookie会发生更新。


六、趁热来一发

在cookie还没有老化的时候,我们再发出请求,会发生什么?——这时候,服务器的响应不再通过set-cookie字段分配cookie,浏览器通过发送的cookie完成身份验证。


七、服务器关闭服务

有一点比较意外的是,session被摧毁的信息并没有预期一样打印出来,这是因为session只有两种途径老化(参考第四点)。那么,当服务器关闭时,是不是意味着session失去了作用?


答应是否定的,这涉及到了会话钝化活化的机制,就是说,session会从服务器内存写进硬盘,等服务器开启时,又活化到内存当中。