JavaWeb之监听器、过滤器

Listener监听器

监听器分类

  1. 第一类:监听请求域对象、会话域对象、全局域对象的创建与销毁
  2. 第二类:监听请求域对象、会话域对象、全局域对象的属性的创建、获取、销毁
  3. 第三类:监听会话域对象的value的绑定与解绑、活化与钝化

第一类监听器

请求域对象

创建:客户端向服务器发送请求时创建

销毁:客户端收到请求并返回响应后销毁

  1. 创建类

    public class RequestServletListener implements ServletRequestListener {
        @Override
        public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
            System.out.println("请求对象被销毁了" + servletRequestEvent);
        }
    
        @Override
        public void requestInitialized(ServletRequestEvent servletRequestEvent) {
            System.out.println("请求对象被创建了" + servletRequestEvent);
        }
    }
    
  2. 配置web.xml文件

    <listener>
        <listener-class>ListenerClassOne.RequestServletListener</listener-class>
    </listener>
    

会话域对象

创建:当服务器使用到了session时创建

销毁:session的过期时间到了就销毁

  1. 创建类

    public class SessionListener implements HttpSessionListener {
    
        @Override
        public void sessionCreated(HttpSessionEvent httpSessionEvent) {
            System.out.println("sessionCreated" + httpSessionEvent.getSession().getId());
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
            System.out.println("sessionDestroyed" + httpSessionEvent.getSession().getId());
        }
    }
    
  2. 配置web.xml文件

    <listener>
        <listener-class>ListenerClassOne.SessionListener</listener-class>
    </listener>
    

全局域对象

创建:当项目启动时创建

销毁:当项目结束时销毁

使用场景:

  1. 初始化与配置(在web.xml中配置<context-param>标签设置参数,通过contextInitialized()方法进行一次性的初始化工作)
  2. 资源清理(在contextDestroyed()中执行必要的清理工作)
  1. 创建类

    public class ServletContextListener implements javax.servlet.ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            System.out.println("ServletContextListener contextInitialized");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            System.out.println("servletContextListener contextDestroyed");
        }
    }
    
  2. 配置web.xml文件

    <listener>
        <listener-class>ListenerClassOne.ServletContextListener</listener-class>
    </listener>
    

第二类监听器

三种监听器都是请求域对象、会话域对象、全局域对象的属性的创建、替换、删除动作进行监听

请求域对象属性

创建类

@WebListener
public class RequestAttrListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("request attribute Added: " + name + ":" + value);
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("request attribute removed: " + name + ":" + value);
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("request attribute replaced: " + name + ":" + value);
    }
}

会话域对象属性

@WebListener
public class SessionAttrListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println("session Attribute Added" + name + ":" + value);
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println("session Attribute Removed" + name + ":" + value);
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println("session Attribute Replaced" + name + ":" + value);
    }
}

全剧域对象属性

@WebListener
public class ServletContextAttrListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("application attribute Added: " + name + ":" + value);
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("application attribute removed: " + name + ":" + value);
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println("application attribute replaced: " + name + ":" + value);
    }
}

第三类监听器

会话域对象的对象属性的绑定与解绑、活化与钝化

该监听器不需要进行web.xml进行配置或者@WebListener注解,

是针对sessionJavaBean属性的监听

主要包括:

  1. 绑定与解绑
  2. 活化与钝化(序列化与反序列化)

假设有一个类User,创建监听器就需要在这个实体类中实现HttpSessionBindingListenerHttpSessionActivationListenerSerializable三个接口

public class User implements HttpSessionBindingListener, HttpSessionActivationListener , Serializable {

    private String name;
    private int age;

    public User() {
    }

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

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
        //从session中添加该对象属性
        System.out.println(this + "被绑定了");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        //从session中移除该对象属性
        System.out.println(this + "被解除绑定了");
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
        //钝化对象属性
        System.out.println("session钝化了" + this);
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        //活化对象属性
        System.out.println("session活化了" + this);
    }
}

活化与钝化还需要额外配置context.xmlweb\META-INF\context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <!--
        maxIdleSwap:"1": session如果1分钟没有使用就序列化
        directory: 序列化后文件所保存的路径
    -->
    <Manager className="org.apache.catalina.session.PersistentManager"
             maxIdleSwap="1">
        <Store className="org.apache.catalina.session.FileStore"
               directory="D:\JAVA\tomcat-demo5\JavaBeanSession" />
    </Manager>
</Context>

对象被序列化之后,会在directory这个路径下生成以sessionid为文件名,以.session为拓展名的文件

  1. 在session的过期时间内,并且服务器正常关闭的情况下,session会钝化对象,重新启动启动服务器,session会活化对象

  2. 如果session超时,则无法活化对象;如果session调用invalidate方法,session无法钝化对象;如果服务器未正常关闭,session无法钝化对象

面试题

  • 钝化:当服务器正常关闭时,还存活着的session(在设置时间内没有销毁) 会随着服务器的关闭被以文件(“SESSIONS.ser”)的形式存储在tomcat 的work 目录下,这个过程叫

做Session 的钝化。

  • 活化:当服务器再次正常开启时,服务器会找到之前的“SESSIONS.ser” 文件,从中恢复之前保存起来的Session 对象,这个过程叫做Session的活化。
  • 想要随着Session 被钝化、活化的对象它的类必须实现Serializable 接口,还有的是只有在服务器正常关闭的条件下,还未超时的Session 才会被钝化成文件。当Session 超时、调用invalidate方法或者服务器在非正常情况下关闭时,Session 都不会被钝化,因此也就不存在活化。
  • 在被钝化成“SESSIONS.ser” 文件时,不会因为超过Session 过期时间而消失,这个文件会一直存在,等到下一次服务器开启时消失。(sesison超时,无法活化)
  • 当多个Session 被钝化时,这些被钝化的Session 都被保存在一个文件中,并不会为每个Session 都建立一个文件。

Filter过滤器

  1. 创建类

    public class MyFilter implements Filter {//继承自Filter
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("过滤器初始化");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("过滤前");
            filterChain.doFilter(servletRequest, servletResponse);
            System.out.println("过滤后");
        }
    
        @Override
        public void destroy() {
            System.out.println("过滤器被销毁了");
        }
    }
    
  2. 在web.xml中配置

    <filter>
        <filter-name>xxx</filter-name>
        <filter-class>Filter.MyFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>xxx</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    

Filter的生命周期

创建:项目启动时创建,先调用构造方法、然后调用init() 方法

销毁:项目正常关闭时销毁,destroy() 方法

注意:Filter是单例模式

思考题:多个Filter的创建顺序?无序,因为底层是多线程

思考题:多个Filter的调用顺序?如果使用web.xml进行配置,则是按照配置顺序(从上到下);如果使用注解@WebFilter进行配置,则是按照类名字进行字典排序

使用注解配置

@WebFilter(urlPatterns = {"/Servlet","/servlet01"}, initParams = {@WebInitParam(name = "name", value = "value")})
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤前");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("过滤后");
    }

    @Override
    public void destroy() {
        System.out.println("过滤器被销毁了");
    }
}

常用参数:

  1. urlPatterns/value: 可以指定需要过滤的资源或者目录
  2. initParams:初始化参数(k-v)

使用场景

  • 自动登录
  • 统一编码格式
  • 控制访问权限
  • 敏感词过滤
  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拖把湛屎,戳谁谁死

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值