侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

Javaweb(12)之监听器Listener

zze
zze
2017-06-22 / 0 评论 / 0 点赞 / 709 阅读 / 10814 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

介绍

监听器用于监听 Web 应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。

监听器的作用实际上就是在特定的时间触发监听器提供给我们重写的钩子函数。

分类及使用

监听器按监听的对象可分为如下几类:

监听 ServletContext

ServletContextListener 监听 ServletContext 对象的创建和销毁:

// com.zze.listener.MyServletContextListener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        /*
         * 初始化时调用
         * */
        System.out.println("初始化");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        /*
         * 销毁时调用(服务器正常关闭或从服务器移除项目时)
         * */
        System.out.println("销毁");
    }
}
<!-- web.xml -->
<listener>
    <listener-class>com.zze.listener.MyServletContextListener</listener-class>
</listener>

ServletContextAttributeListener 监听对 ServletContext 属性操作:

// com.zze.listener.MyServletContextAttributeListener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("添加属性时触发");
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("移除属性时触发");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("修改属性时触发");
    }
}
<!-- web.xml -->
<listener>
    <listener-class>com.zze.listener.MyServletContextAttributeListener</listener-class>
</listener>

监听 HttpSession

HttpSessionListener 监听 Session 对象的创建和销毁:

// com.zze.listener.MyHttpSessionListener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("session 创建时调用");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("session 销毁时调用");
    }
}
<!-- web.xml -->
<listener>
    <listener-class>com.zze.listener.MyHttpSessionListener</listener-class>
</listener>

HttpSessionAttributeListener 监听 Session 中的属性操作:

// com.zze.listener.MyHttpSessionAttributeListener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {

    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("添加属性时触发");
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("移除属性时触发");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("修改属性时触发");
    }
}
<!-- web.xml -->
<listener>
    <listener-class>com.zze.listener.MyHttpSessionAttributeListener</listener-class>
</listen

HttpSessionBindingListener 监听对象在 Session 中的绑定和解绑操作:

// com.zze.bean.User;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class User implements HttpSessionBindingListener {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("被绑定到 session");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("从 session 中解绑");
    }
}
// com.zze.servlet.TestServlet;
import com.zze.com.zze.bean.User;

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 java.io.IOException;

@WebServlet("/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.setAttribute("user", new User()); // 绑定 触发 valueBound
        session.removeAttribute("user");// 解绑 触发 valueUnbound
    }
}

HttpSessionActivationListener 监听对象在 Session 中的钝化与活化:

// com.zze.bean.User

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;

public class User implements HttpSessionActivationListener,Serializable {
    private String name;
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("钝化");
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        System.out.println("活化");
    }
}
// com.zze.servlet.TestServlet;

import com.zze.com.zze.bean.User;

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;

@WebServlet("/test")
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        HttpSession session = req.getSession();
        session.setAttribute("user", new User("zhangsan",19)); // 存储到 session
    }
}

钝化:将内存中的数据序列化保存到硬盘。
活化:将硬盘中的数据反序列化加载到内存。

Session 的钝化和活化用意何在?
Session 中的值可能会很多,并且可能我们很长一段时间都不会使用这个值,那么可以考虑将 Session 中的值存储到硬盘,等要使用的时候再从硬盘中提取,减轻内存压力。
默认情况下,在服务器正常关闭时会钝化保存在 Session 中的数据,而在服务器再次启动时会活化之前钝化的数据。

配置钝化活化:

<!-- context.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--maxIdleSwap :设置间隔多久时间钝化,单位为分钟-->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<!--directory:session 钝化保存的目录-->
<Store className="org.apache.catalina.session.FileStore" directory="sessionDir"/>
</Manager>
</Context>
  1. 在 Tomcat 目录下 /conf/context.xml 中配置以上内容,对托管到当前服务器的所有程序生效。
  2. 在 Tomcat 目录下 /conf/Catalina/localhost/context.xml 中配置以上内容,对托管到当前服务器中使用 localhost 访问的程序生效。
  3. 在项目目录下 /META-INF/context.xml 中配置以上内容,仅对当前项目生效。

注意:因为钝化和活化实际上是序列化和反序列化的过程,所以要钝化的对象类必须实现 Serializable 接口。

监听 HttpServletRequest

ServletRequestListener 监听 HttpServletRequest 对象的创建和销毁:

// com.zze.listener.MyServletRequestListener

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class MyServletRequestListener implements ServletRequestListener {

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("初始化");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("销毁");
    }

}
<!-- web.xml -->
<listener>
    <listener-class>com.zze.listener.MyServletRequestListener</listener-class>
</listener>

ServletRequestAttributeListener 监听 Request 中的属性操作:

// com.zze.listener.MyServletRequestAttributeListener

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;

public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("添加属性时触发");
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("移除属性时触发");
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("修改属性时触发");
    }
}
<!-- web.xml -->
<listener>
    <listener-class>com.zze.listener.MyServletRequestAttributeListener</listener-class>
</listener>
0

评论区