zoukankan      html  css  js  c++  java
  • springboot中使用过滤器、拦截器、监听器

      监听器:listener是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件。用于在事件发生前、发生后做一些必要的处理。其主要可用于以下方面:1、统计在线人数和在线用户2、系统启动时加载初始化信息3、统计网站访问量4、记录用户访问路径。

      过滤器:Filter是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

      拦截器:Interceptor 在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。比如日志,安全等。一般拦截器方法都是通过动态代理的方式实现。可以通过它来进行权限验证,或者判断用户是否登陆,或者是像12306 判断当前时间是否是购票时间。

      过滤器Filter只在Servlet前后起作用,而拦截器Interceptor可以深入到方法前后,异常抛出前后等,具有更大的弹性。所以在Spring的程序里应该尽量用拦截器,在简单的java—web项目里可以使用较为简单的过滤器。

    ==========1.过滤器的使用===========

      过滤器的使用有两种方式。

    1.基于注册的方式

      这种使用方式简单:编写过滤器、注入到spring中。

    过滤器1:

    package cn.qlq.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    
    public class MyFilter implements Filter {
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("=========enter filter===========");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
    
        }
    
    }

    过滤器2:

    package cn.qlq.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    public class MyFilter2 implements Filter {
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("=========enter filter (MyFilter2)===========");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
    
        }
    
    }

    注册到spring中:(这种注册方式的顺序可以过滤器的指定)

    package cn.qlq.config;
    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import cn.qlq.filter.MyFilter;
    import cn.qlq.filter.MyFilter2;
    
    /**
     * 注册filter,setOrder可以控制顺序
     * 
     * @author Administrator
     *
     */
     @Configuration
    public class FilterConfig {
    
        @Bean
        public FilterRegistrationBean registMyFilter() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new MyFilter());
            registration.addUrlPatterns("/*");
            registration.setName("myFilter");
            registration.setOrder(2);
            return registration;
        }
    
        @Bean
        public FilterRegistrationBean registMyFilter2() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new MyFilter2());
            registration.addUrlPatterns("/*");
            registration.setName("myFilter2");
            registration.setOrder(1);
            return registration;
        }
    }

    测试:

    2.基于注解的方式

      这种方式只需要在过滤器加上注解@WebFilter即可。过滤器的执行顺序是按照类名的字母顺序进行过滤。这种方式需要在springboot的运行类增加@ServletComponentScan注解。ServletComponentScan注解的为了Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码

    package cn.qs;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    
    @SpringBootApplication
    // Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
    @ServletComponentScan("cn")
    public class MySpringBootApplication {
        public static void main(String[] args) {
            // 入口运行类
            SpringApplication.run(MySpringBootApplication.class, args);
        }
    }
    package cn.qlq.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    
    /**
     * 注解配置的filter执行顺序按类名的顺序执行
     */
    @WebFilter(filterName = "myFilter", urlPatterns = "/*")
    public class MyFilter implements Filter {
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("=========enter filter===========");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
    
        }
    
    }
    package cn.qlq.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    
    @WebFilter(filterName = "myFilter2", urlPatterns = "/*")
    public class MyFilter2 implements Filter {
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("=========enter filter (MyFilter2)===========");
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
    
        }
    
    }

    测试:

    ==============2.拦截器的使用==================

       拦截器的使用方法是先编写拦截器,然后注册到spring。拦截器的执行顺序是按照其注册顺序拦截。

    package cn.qlq.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class MyInterceptor1 implements HandlerInterceptor {
    
        /**
         * 在请求处理之前进行调用(Controller方法调用之前)
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
    
            System.out.println("被 MyInterceptor1  postHandle拦截,放行...");
            return true;
    
        }
    
        /**
         * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView mv)
                throws Exception {
            System.out.println("被 MyInterceptor1 postHandle 拦截,放行...");
        }
    
        /**
         * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行 (主要是用于进行资源清理工作)
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex)
                throws Exception {
            System.out.println("被 MyInterceptor1 afterCompletion 拦截,放行...");
        }
    }
    package cn.qlq.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class MyInterceptor2 implements HandlerInterceptor {
    
        /**
         * 在请求处理之前进行调用(Controller方法调用之前)
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
    
            System.out.println("被 MyInterceptor2  postHandle拦截,放行...");
            return true;
    
        }
    
        /**
         * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView mv)
                throws Exception {
            System.out.println("被 MyInterceptor2 postHandle 拦截,放行...");
        }
    
        /**
         * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行 (主要是用于进行资源清理工作)
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex)
                throws Exception {
            System.out.println("被 MyInterceptor2 afterCompletion 拦截,放行...");
        }
    }

    注册到spring中:

    package cn.qlq.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    import cn.qlq.interceptor.MyInterceptor1;
    import cn.qlq.interceptor.MyInterceptor2;
    
    /**
     * 注册拦截器
     * 
     * @author Administrator
     *
     */
    @Configuration
    public class InterceptorConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            /**
             * 拦截器按照顺序执行
             */
            registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/th/**").addPathPatterns("/freemarker/**");
            registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/freemarker/**");
    
            super.addInterceptors(registry);
        }
    
    }

    =============3.监听器的使用=================

      监听器的使用与过滤器使用差不多,也是先编写监听器,然后注入到spring中。

    package cn.qlq.listener;
    
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    
    public class MyHttpSessionListener implements HttpSessionListener {
    
        public static int online = 0;
    
        @Override
        public void sessionCreated(HttpSessionEvent se) {
            System.out.println("创建session,在线用户数:" + (++online));
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            System.out.println("销毁session,在线用户数:" + (--online));
            online--;
        }
    }
    package cn.qlq.listener;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    public class MyServletContextListener implements ServletContextListener {
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("容器创建");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("容器销毁");
        }
    
    }

    注入到spring中:

    package cn.qlq.config;
    
    import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import cn.qlq.listener.MyHttpSessionListener;
    import cn.qlq.listener.MyServletContextListener;
    
    /**
     * 
     * @author Administrator
     *
     */
    @Configuration
    public class ListenerConfig {
        @Bean
        public ServletListenerRegistrationBean<MyHttpSessionListener> listenerRegist() {
            ServletListenerRegistrationBean<MyHttpSessionListener> srb = new ServletListenerRegistrationBean<MyHttpSessionListener>();
            srb.setListener(new MyHttpSessionListener());
            return srb;
        }
    
        @Bean
        public ServletListenerRegistrationBean<MyServletContextListener> listenerRegist2() {
            ServletListenerRegistrationBean<MyServletContextListener> srb = new ServletListenerRegistrationBean<MyServletContextListener>();
            srb.setListener(new MyServletContextListener());
            return srb;
        }
    
    }

    测试:

    补充:当然监听器可以使用注解方式,如下:

    package cn.qs.listener;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.annotation.WebListener;
    @WebListener
    public class StartListener implements ServletContextListener {
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("容器启动");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("容器销毁");
        }
    
    }
  • 相关阅读:
    第七周-学习进度条
    《梦断代码》阅读笔记01
    第六周-学习进度条
    构建之法阅读笔记03
    结对项目开发(石家庄地铁乘车系统)
    第五周-学习进度条
    第四周-学习进度条
    HDU--1272 小希的迷宫(并查集判环与联通)
    HDU--1856 More is better(简单带权并查集)
    HDU--3635 带权并查集
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/10409588.html
Copyright © 2011-2022 走看看