ServletContextListener
监听ServletContext的创建与销毁,一般是启动或停止服务器时会触发
package me.zhao.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ServletContextListenerTest implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContextListener contextDestroyed");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContextListener contextInitialized");
}
}
ServletContextAttributeListener
监听ServletContext中属性的改变,包括新增属性、修改属性和删除属性
// 在ServletContextListenerTest的contextInitialized方法中添加几行
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContextListener contextInitialized");
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("name", "张三");
servletContext.setAttribute("age", 20);
servletContext.setAttribute("name", "李四");
servletContext.removeAttribute("name");
// sex属性本来不存在
servletContext.removeAttribute("sex");
}
ServletContextAttributeListener
package me.zhao.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ServletContextAttributeListenerTest implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
System.out.println("ServletContextAttributeListener attributeAdded " + event.getName());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
System.out.println("ServletContextAttributeListener attributeRemoved " + event.getName());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
System.out.println("ServletContextAttributeListener attributeReplaced " + event.getName());
}
}
注意点
- 日志中
没有打印性别sex
相关的信息,只有删除已经存在的属性时才会执行attributeRemoved
方法 - 日志中
attributeReplaced
打印的name是张三,而不是李四,说明getValue()方法返回的是替换之前
的属性值
HttpSessionListener
监听session的创建和销毁
package me.zhao.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class HttpSessionListenerTest implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("sessionCreated " + se.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("sessionDestroyed " + se.getSession().getId());
}
}
HttpSessionAttributeListener
监听HttpSession中属性的改变,包括新增属性、修改属性和删除属性
package me.zhao.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener
public class HttpSessionAttributeListenerTest implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println("HttpSessionAttributeListener attributeAdded "
+ event.getName() + " " + event.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.println("HttpSessionAttributeListener attributeRemoved "
+ event.getName() + " " + event.getValue());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.println("HttpSessionAttributeListener attributeReplaced "
+ event.getName() + " " + event.getValue());
}
}
// 测试的Servlet
@WebServlet("/test")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
// 将session timeout设置为60秒
session.setMaxInactiveInterval(60);
session.setAttribute("name", "张三");
session.setAttribute("age", 20);
session.setAttribute("name", "李四");
session.removeAttribute("name");
// sex属性本来不存在
session.removeAttribute("sex");
response.getWriter().append("Served at: ").append(request.getContextPath());
}
}
从结果可以看出HttpSessionAttributeListener 和 ServletContextAttributeListener的实现方式是相似的。
attributeRemoved
方法只有删除已经存在的属性时才会执行attributeReplaced
getValue()方法返回的是替换之前
的属性值
HttpSessionBindingListener
package me.zhao.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
@WebListener
public class HttpSessionBindingListenerTest implements HttpSessionBindingListener{
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("HttpSessionBindingListener valueBound " + event.getName());
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("HttpSessionBindingListener valueUnbound " + event.getName());
}
}
// 测试Servlet
package me.zhao.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import me.zhao.listener.HttpSessionBindingListenerTest;
@WebServlet("/test2")
public class TestServlet2 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("user1", new HttpSessionBindingListenerTest());
session.setAttribute("user1", new HttpSessionBindingListenerTest());
session.removeAttribute("user1");
session.removeAttribute("user2");
response.getWriter().append("Served at: ").append(request.getContextPath());
}
}
HttpSessionBindingListener的几个特点
首次添加
属性时会执行valueBound,同时也会执行HttpSessionAttributeListener的attributeAdded,如图1修改
属性时会执行valueBound和valueUnbound,同时也会执行HttpSessionAttributeListener的attributeReplaced,如图2删除
属性时会执行valueUnbound,只有删除已存在的属性时会执行,同时也会执行HttpSessionAttributeListener的attributeRemoved,如图3、图4
HttpSessionBindingListener、HttpSessionAttributeListener的区别
- 只有当实现了
HttpSessionBindingListener
的类,在绑定到session时才会触发相应事件 - 不管属性值有没有实现
HttpSessionBindingListener
接口,都会触发HttpSessionAttributeListener的相应事件 - 触发HttpSessionBindingListener时会同时触发HttpSessionAttributeListener的区别,反之不会
- 当session的属性有任何的变化,servlet容器都会通知HttpSessionAttributeListener。但是对于HttpSessionBindingListener,只有当绑定或解绑的属性值是监听器的实例时,servlet容器才会通知
HttpSessionActivationListener
监听session的钝化与激活
钝化是指服务器内存不够了或者session的活动超时时间到了,把最近不活动的session序列化到磁盘。激活是指某个钝化的session又被访问了,从磁盘将session反序列化到内存。
public interface HttpSessionActivationListener extends EventListener {
public void sessionWillPassivate(HttpSessionEvent se);
public void sessionDidActivate(HttpSessionEvent se);
}
ServletRequestListener
当请求初始化或者销毁时,即客户端请求进入web应用(进入servlet或者第一个filter)或web应用返回响应给客户端(退出servlet或者第一个filter)。
package me.zhao.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ServletRequestListenerTest implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("ServletRequestListener requestDestroyed");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("ServletRequestListener requestInitialized");
}
}
ServletRequestAttributeListener
监听ServletRequest的属性变化
package me.zhao.listener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ServletRequestAttributeListenerTest implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent event) {
System.out.println("ServletRequestAttributeListener attributeAdded "
+ event.getName() + " " + event.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent event) {
System.out.println("ServletRequestAttributeListener attributeRemoved "
+ event.getName() + " " + event.getValue());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent event) {
System.out.println("ServletRequestAttributeListener attributeReplaced "
+ event.getName() + " " + event.getValue());
}
}
// 测试Servlet
package me.zhao.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/test3")
public class TestServlet3 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("name", "张三");
request.setAttribute("age", 20);
request.setAttribute("name", "李四");
request.removeAttribute("name");
// sex属性本来不存在
request.removeAttribute("sex");
response.getWriter().append("Served at: ").append(request.getContextPath());
}
}
参考文章
- HttpSessionBindingListener和HttpSessionAttributeListener区别
- HttpSessionBindingListener
- 详解JavaWeb中的 Listener
完整代码
https://gitee.com/zhaobingshuang/study/tree/master/javaweb-listener