• Tomcat深入浅出——Filter与Listener(五)


    一、Filter过滤器

    1.1 Filter过滤器的使用

    • 这是过滤器接口的方法
    public interface Filter {
        default void init(FilterConfig filterConfig) throws ServletException {
        }
    
        void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    
        default void destroy() {
        }
    }
    
    • 一般情况下我们都在过滤器中添加公共的代码
    • 例如我们经常设置字符编码utf-8,为了减少重复的操作,我们直接在过滤器中设置即可。
    @WebFilter("/*")
    public class MyFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            //在Filter对象第一次被创建的时候调用,并且只调用一次
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            //doFilter()只要用户发送一次请求,则执行一次,发送N次,则执行N次。在这个方法中编写过滤规则
            System.out.println("doFilter方法,前1");
            //解决跨域问题
            HttpServletResponse resp = (HttpServletResponse) servletResponse;
            resp.setHeader("Access-Control-Allow-Origin", "*");
            resp.setHeader("Access-Control-Allow-Headers", "*");
            resp.setHeader("Access-Control-Allow-Method", "*");
    
            //执行下一个过滤器,如果说下一个不是过滤器,则会执行servlet
            filterChain.doFilter(servletRequest,servletResponse);
            System.out.println("doFilter方法,后1");
        }
    
    
        @Override
        public void destroy() {
            //在Filter对象被释放/销毁之前调用,并且只调用一次
            System.out.println("destroy方法");
        }
    }
    
    折叠
    • init方法:在Filter对象第一次被创建的时候调用,并且只调用一次

    • doFilter方法:只要用户发送一次请求,则执行一次,发送N次,则执行N次。在这个方法中编写过滤规则

    • destroy方法:在Filter对象被释放/销毁之前调用,并且只调用一次

    • filterChain.doFilter(request, response);执行下一个过滤器,如果下一个不是过滤器,则执行Servlet

    目标Servlet是否执行取决于两个条件:

    • 过滤器中是否编写了filterChain.doFilter(request, response);
    • 用户发的请求路径是否和Servlet的请求路径一致

    注意:

    • Filter的优先级天生就比Servlet高
    • 使用@WebFilter的时候,Filter执行顺序根据类名顺序执行。
    • Filter的生命周期与Servlet一样,但是Filter会在服务器启动的时候就默认创建对象,而Servlet却需要配置才可以。
    • 如果在web.xml中配置两个或者多个过滤器时,执行顺序根据<filter-mapping>的先后。

    1.2 Filter的责任链设计模式

    • 我们先来看一下两个过滤器的运行过程是什么样的

    • Filter过滤器的doFilter方法,执行顺序遵循的是栈结构,但是过滤器本身的生命周期就和队列差不多吧。
    • 其实doFilter方法,就是一种责任链设计模式!
    //模仿栈
    //模仿Filter设计模式
    //缺点:在编译阶段已经完全确定了调用关系
    //如果想要改变调用顺序,必须要修改java代码
    //违背了OCP原则(开闭原则)
    public class Test {
        public static void main(String[] args) {
            System.out.println("main方法执行");
            m1();
            System.out.println("main执行完毕");
        }
        public static void m1() {
            System.out.println("m1方法执行");
            m2();
            System.out.println("m1执行完毕");
        }
        public static void m2() {
            System.out.println("m2方法执行");
            m3();
            System.out.println("m2执行完毕");
        }
        public static void m3() {
            System.out.println("目标正在执行中");
        }
    }
    

    • 这是执行的结果,是不是和Filter一样~~~🎇

    二、Listener监听器

    • 监听器顾名思义:起到了监听的作用,我想大家在javaGUI部分也了解过吧。
    • 监听器可以监测我们网站时时的在线人数等等
    • 监听器加上@WebListener注解或者在web.xml中配置一下即可,并不需要我们程序员去调用
    • 下面是一个session监听器
    @WebListener
    public class MyListener01 implements HttpSessionAttributeListener {
    
        //监听session行为的监听器
        @Override
        public void attributeAdded(HttpSessionBindingEvent se) {
            System.out.println("add");
        }
    
        @Override
        public void attributeRemoved(HttpSessionBindingEvent se) {
            System.out.println("removed");
        }
    
        @Override
        public void attributeReplaced(HttpSessionBindingEvent se) {
            System.out.println("replaced");
        }
    }
    
    • 下面是监听整个Servlet生命周期的监听器
    @WebListener
    public class MyListener implements ServletContextListener {
    
        //监听整个servlet生命周期的监听器
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("contextInitialized");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("contextDestroyed");
        }
    }
    
    • 感觉用途不是特别多,我了解的也比较少,就先介绍这么多,感谢你的认真阅读🚀

    三、结尾

    • 对于Tomcat的Servlet内容就总结这么多,若想深入学习等待后续更新。
    • 我将会继续更新关于Java方向的学习知识,感兴趣的小伙伴可以关注一下。
    • 文章写得比较走心,用了很长时间,绝对不是copy过来的!
    • 尊重每一位学习知识的人,同时也尊重每一位分享知识的人。
    • 😎你的点赞与关注,是我努力前行的无限动力。🤩
  • 相关阅读:
    Pandas常用数据结构
    GUI进阶:用Java实现可DIY的音乐计算器v0.33
    Sentinel注解@SentinelResource详解
    螺杆支撑座有哪些品牌?
    2023年咸阳市《网络建设与运维》赛题解析------三、无线配置
    Entity Framework Core 7批量数据插入实现高速化
    python正则表达式
    PAT乙级1042 字符统计
    Python布尔类型、运算符
    前端的那些基本标签【a table tr caption image等等......】
  • 原文地址:https://www.cnblogs.com/lx-meteor/p/16463863.html