• SpringBoot:整合监听器/过滤器和拦截器


    整合监听器/过滤器和拦截器

    在实际开发过程中,经常会碰见一些比如系统启动初始化信息、统计在线人数、在线用户数、过滤敏/高词汇、访问权限控制(URL级别)等业务需求。实现以上的功能,都会或多或少的用到过滤器监听器拦截器

    一.SpringBoot整合过滤器Filter

    过滤器Filter,是Servlet的的一个实用技术了。可以通过过滤器,对请求进行拦截处理。

    1.编写Filter过滤器

    1. 编写普通Java类实现接口Filter。

    2. 使用注解@WebFilter标注过滤器类,并配置过滤url。

    @WebFilter("/*")// 当前配置拦截所有请求
    public class TestFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("过滤器Filter测试执行…………");
            chain.doFilter(request, response);// 放行
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    说明:@WebFilterServlet3.0新增的注解,原先实现过滤器,需要在web.xml中进行配置,而现在通过此注解,启动启动时会自动扫描自动注册。

    1. 在启动类加入@ServletComponentScan注解
      使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册。

    2. 开启启动类,访问测试,查看控制台结果

    当注册多个过滤器时,无法指定执行顺序,早期使用web.xml配置过滤器时,是可指定执行顺序,但使用注解@WebFilter时,没有顺序这个配置属性。通常情况下,如果对过滤器有特定顺序要求的,我们推荐采用原始方式配置,或者参考测试结果:执行顺序和类名字符排序有关。另外SpringBoot也为解决这个问题,单独提供了一个类FilterRegistrationBean,此类提供setOrder方法,可以为filter设置排序值,让Spring在注册Filter之前排序后再依次注册。

    2.解决多过滤器执行顺序问题

    1. 编写两个/以上Filter,修改Filter的实现(去除注解@WebFilter即可,其他代码无需改动)

    2. 编写一个config配置类,利用FilterRegistrationBean实现注册过滤器。

      FilterRegistrationBean是SpringBoot提供的用于注册和

      解决Filter执行顺序问题

      的类。注意在类上使用注解@Configuration,在方法上使用注解@Bean。

    @Configuration    // 标注为Spring配置beans组件
    public class FilterConfig {
    
        // 注册第一个Filter
        @Bean // 标注为Spring配置bean组件
        public FilterRegistrationBean<Filter> registerFilter1() {
            //通过FilterRegistrationBean实例设置优先级可以生效
            FilterRegistrationBean<Filter> registrationBean = new  FilterRegistrationBean<>();
            // 注册自定义过滤器
            registrationBean.setFilter(new TestFilter1());
            // 设置过滤器的名字
            registrationBean.setName("filter01");
            // 设置过滤器的名字过滤路径
            registrationBean.addUrlPatterns("/*");
            // 设置过滤器优先级:最顶级
            registrationBean.setOrder(1);
            return registrationBean;
        }
    
        @Bean
        public FilterRegistrationBean<Filter> registerFilter2() {
            FilterRegistrationBean<Filter> registrationBean = new  FilterRegistrationBean<>();
            // 注册第二个自定义过滤器TestFilter2
            registrationBean.setFilter(new TestFilter2());
            registrationBean.setName("filter02");
            registrationBean.addUrlPatterns("/*");
            registrationBean.setOrder(5);
            return registrationBean;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    1. 开启启动类,访问测试,查看控制台结果
      说明:这种方式可以不使用注解@ServletComponentScan

    二.SpringBoot整合监听器Listnner

    Listnner是servlet规范中定义的一种特殊类。用于监听ServletContext、HttpSession和servletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件。用于在事件发生前、发生后做一些必要的处理。一般是获取在线人数等业务需求。

    1. 创建普通类实现监听器接口(比较多,我就不一一列出了)

      本次案例:创建了

      ServletRequest

      监听器,实现接口

      ServletRequestListnner

    @WebListener
    @Slf4j  // 该注解等价于Logger  log = new Logger(。。。。)
    public class TestListnner implements ServletRequestListener {
        @Override
        public void requestInitialized(ServletRequestEvent sre) {
            log.info("ServletRequest出生…………");
        }
    
        @Override
        public void requestDestroyed(ServletRequestEvent sre) {
            log.info("ServletRequest销毁…………");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 在启动类加入@ServletComponentScan注解
      使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册。

    2. 开启启动类,访问测试,查看控制台结果

    三.SpringBoot整合拦截器HandlerInterceptor

    以上的过滤器、监听器都属于Servlet的API,我们在开发中过滤web请求时,还可以使用Spring提供的拦截器(HandlerInterceptor)进行更加精细的控制。

    1. 编写普通类实现接口HandlerInterceptor。
    @Slf4j
    public class TestHandlerInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            log.info("preHandle请求访问前,拦截执行……");
            // 返回 false 则请求中断
            return  true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            log.info("postHandle请求访问后,执行……");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            log.info("afterCompletion请求调用完成后回调方法,即在视图渲染完成后回调……");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1. 编写普通类继承

    WebMvcConfigurerAdapter配置类是spring提供的一种配置方式,采用JavaBean的方式替代传统的基于xml的配置来对spring框架进行自定义的配置,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。因此,在spring boot提倡的基于注解的配置,采用“约定大于配置”的风格下,当需要进行自定义的配置时,便可以继承WebMvcConfigurerAdapter这个抽象类,通过JavaBean来实现需要的配置。
      WebMvcConfigurerAdapter是一个抽象类,它只提供了一些空的接口让用户去重写,比如如果想添加拦截器的时候,需要去重写一下addInterceptors()这个方法,去配置自定义的拦截器。我们可以看一下WebMvcConfigurerAdapter提供了哪些接口来供我们使用。

    public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
        /*配置路径匹配参数*/
        public void configurePathMatch(PathMatchConfigurer configurer) {}
        /*配置Web Service或REST API设计中内容协商,即根据客户端的支持内容格式情况来封装响应消息体,如xml,json*/
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
        /*配置路径匹配参数*/
        public void configureAsyncSupport(AsyncSupportConfigurer configurer) {}
        /* 使得springmvc在接口层支持异步*/
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}
        /* 注册参数转换和格式化器*/
        public void addFormatters(FormatterRegistry registry) {}
        /* 注册配置的拦截器*/
        public void addInterceptors(InterceptorRegistry registry) {}
        /* 自定义静态资源映射*/
        public void addResourceHandlers(ResourceHandlerRegistry registry) {}
        /* cors跨域访问*/
        public void addCorsMappings(CorsRegistry registry) {}
        /* 配置页面直接访问,不走接口*/
        public void addViewControllers(ViewControllerRegistry registry) {}
        /* 注册自定义的视图解析器*/
        public void configureViewResolvers(ViewResolverRegistry registry) {}
        /* 注册自定义控制器(controller)方法参数类型*/
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {}
        /* 注册自定义控制器(controller)方法返回类型*/
        public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {}
        /* 重载会覆盖掉spring mvc默认注册的多个HttpMessageConverter*/
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}
        /* 仅添加一个自定义的HttpMessageConverter,不覆盖默认注册的HttpMessageConverter*/
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}
        /* 注册异常处理*/
        public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
        /* 多个异常处理,可以重写次方法指定处理顺序等*/
        public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    Spring 5.0/SpringBoot 2.0 后,WebMvcConfigurerAdapter被废弃,取代的方法有两种:

    ①implements WebMvcConfigurer(官方推荐)

    ②extends WebMvcConfigurationSupport

    @Configuration  // 标注为Spring组件
    public class HandlerInterceptorConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 添加一个实现HandlerInterceptor接口的拦截器实例
            registry.addInterceptor(new TestHandlerInterceptor())
                // 用于设置拦截器的过滤路径规则
                .addPathPatterns("/**")
                // 用于设置不需要拦截的过滤规则
                .excludePathPatterns("/emp/toLogin","/emp/login", "/js/**", "/css/**", "/images/**");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意在类上添加注解@Configuration标注为Spring组件

    1. 开启启动类,访问测试,查看控制台结果

    一张图理解过滤器,拦截器执行

    img

    目前互联网上很多大佬都有SpringBoot系列教程,如有雷同,请多多包涵了。画图太费事了,图片来源于网络。

    原文地址:https://www.cnblogs.com/xsge/p/13915775.html

    https://www.cnblogs.com/xsge/

  • 相关阅读:
    Pandas get_dummies用法
    无货源操作方式
    MySQL数据备份与恢复
    jeecgboot vue3使用JAreaSelect地区选择组件时返回省市区的编码,如何获取到选择地区的文字
    python -【十】单例模式与工厂模式
    【好文收藏】【持续更新】今天你机器学习了吗
    【Matlab】状态空间模型的最小化实现 minreal() 函数
    Oracle/PLSQL: Rank Function
    高频面试题
    习题练习 C语言(暑期第四弹)
  • 原文地址:https://blog.csdn.net/qq_43842093/article/details/126446070