SpringBoot第五集:整合监听器/过滤器和拦截器(2020最新最易懂)

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

一.SpringBoot整合过滤器Filter  

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

1.编写Filter过滤器

  1. 编写普通Java类实现接口Filter。
  2. 使用注解@WebFilter标注过滤器类,并配置过滤url。
     1 @WebFilter("/*")// 当前配置拦截所有请求
    2 public class TestFilter implements Filter {
    3
    4 @Override
    5 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    6 throws IOException, ServletException {
    7 System.out.println("过滤器Filter测试执行…………");
    8 chain.doFilter(request, response);// 放行
    9 }
    10
    11 }

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

  3. 在启动类加入@ServletComponentScan注解
    使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册。
  4. 开启启动类,访问测试,查看控制台结果

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

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

  1. 编写两个/以上Filter,修改Filter的实现(去除注解@WebFilter即可,其他代码无需改动)
  2. 编写一个config配置类,利用FilterRegistrationBean实现注册过滤器。
    FilterRegistrationBean是SpringBoot提供的用于注册和解决Filter执行顺序问题的类。注意在类上使用注解@Configuration,在方法上使用注解@Bean。
     1 @Configuration    // 标注为Spring配置beans组件
    2 public class FilterConfig {
    3
    4 // 注册第一个Filter
    5 @Bean // 标注为Spring配置bean组件
    6 public FilterRegistrationBean<Filter> registerFilter1() {
    7 //通过FilterRegistrationBean实例设置优先级可以生效
    8 FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
    9 // 注册自定义过滤器
    10 registrationBean.setFilter(new TestFilter1());
    11 // 设置过滤器的名字<filter-name>
    12 registrationBean.setName("filter01");
    13 // 设置过滤器的名字过滤路径<url-partten>
    14 registrationBean.addUrlPatterns("/*");
    15 // 设置过滤器优先级:最顶级
    16 registrationBean.setOrder(1);
    17 return registrationBean;
    18 }
    19
    20 @Bean
    21 public FilterRegistrationBean<Filter> registerFilter2() {
    22 FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
    23 // 注册第二个自定义过滤器TestFilter2
    24 registrationBean.setFilter(new TestFilter2());
    25 registrationBean.setName("filter02");
    26 registrationBean.addUrlPatterns("/*");
    27 registrationBean.setOrder(5);
    28 return registrationBean;
    29 }
    30
    31 }
  3. 开启启动类,访问测试,查看控制台结果
    说明:这种方式可以不使用注解@ServletComponentScan

二.SpringBoot整合监听器Listnner

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

  1. 创建普通类实现监听器接口(比较多,我就不一一列出了)
    本次案例:创建了ServletRequest监听器,实现接口ServletRequestListnner

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

三.SpringBoot整合拦截器HandlerInterceptor

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

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

     1 @Slf4j
    2 public class TestHandlerInterceptor implements HandlerInterceptor {
    3
    4 @Override
    5 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    6 throws Exception {
    7 log.info("preHandle请求访问前,拦截执行……");
    8 // 返回 false 则请求中断
    9 return true;
    10 }
    11
    12 @Override
    13 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    14 ModelAndView modelAndView) throws Exception {
    15 log.info("postHandle请求访问后,执行……");
    16 }
    17
    18 @Override
    19 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    20 throws Exception {
    21 log.info("afterCompletion请求调用完成后回调方法,即在视图渲染完成后回调……");
    22 }
    23
    24 }
  2. 编写普通类继承WebMvcConfigurerAdapter注解拦截器
      
    WebMvcConfigurerAdapter配置类是spring提供的一种配置方式,采用JavaBean的方式替代传统的基于xml的配置来对spring框架进行自定义的配置,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter。因此,在spring boot提倡的基于注解的配置,采用“约定大于配置”的风格下,当需要进行自定义的配置时,便可以继承WebMvcConfigurerAdapter这个抽象类,通过JavaBean来实现需要的配置。
      WebMvcConfigurerAdapter是一个抽象类,它只提供了一些空的接口让用户去重写,比如如果想添加拦截器的时候,需要去重写一下addInterceptors()这个方法,去配置自定义的拦截器。我们可以看一下WebMvcConfigurerAdapter提供了哪些接口来供我们使用。

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

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

    ①implements  WebMvcConfigurer(官方推荐)

    ②extends  WebMvcConfigurationSupport

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

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

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

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

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

SpringBoot第五集:整合监听器/过滤器和拦截器(2020最新最易懂)的更多相关文章

  1. SpringBoot第三集:热部署与单元测试(2020最新最易懂)

    SpringBoot第三集:热部署与单元测试(2020最新最易懂) 有兴趣的可以先参考附录简单了解SpringBoot自动装配流程. 一.SpringBoot开发热部署 项目开发中,你是否也遇到更新配 ...

  2. springBoot之配置文件的读取以及过滤器和拦截器的使用

    前言 在之前的学习springBoot中,成功的实现了Restful风格的基本服务.但是想将之前的工程作为一个项目来说,那些是仅仅不够的.可能还需要获取自定义的配置以及添加过滤器和拦截器.至于为什么将 ...

  3. SpringBoot第九集:整合JSP和模板引擎Freemarker/Thymeleaf(2020最新最易懂)

    SpringBoot第九集:整合JSP和模板引擎(2020最新最易懂) 当客户通过前端页面提交请求后,我们以前是怎么做的?后端接收请求数据,处理请求,把响应结果交给模板引擎JSP,最后将渲染后的JSP ...

  4. SpringBoot第二集:注解与配置(2020最新最易懂)

    2020最新SpringBoot第二集:基础注解/基础配置(2020最新最易懂) 一.Eclipse安装SpringBoot插件 Eclipse实现SpringBoot开发,为便于项目的快速构建,需要 ...

  5. SpringBoot第五集:整合Druid和MyBatis(2020最新最易懂)

    SpringBoot第五集:整合Druid和MyBatis(2020最新最易懂) 1.SpringBoot整合Druid Druid是阿里巴巴的一个开源项目,是一个数据库连接池的实现,结合了C3P0. ...

  6. SpringBoot第四集:整合JdbcTemplate和JPA(2020最新最易懂)

    SpringBoot第四集:整合JdbcTemplate和JPA(2020最新最易懂) 当前环境说明: Windows10_64 Maven3.x JDK1.8 MySQL5.6 SpringTool ...

  7. springboot配置监听器、过滤器和拦截器

    监听器:listener是servlet规范中定义的一种特殊类.用于监听servletContext.HttpSession和servletRequest等域对象的创建和销毁事件.监听域对象的属性发生 ...

  8. SpringBoot第七集:异常处理与整合JSR303校验(2020最新最易懂)

    SpringBoot第七集:异常处理与整合JSR303校验(2020最新最易懂) 一.SpringBoot全局异常 先讲下什么是全局异常处理器? 全局异常处理器就是把整个系统的异常统一自动处理,程序员 ...

  9. SpringBoot第十一集:整合Swagger3.0与RESTful接口整合返回值(2020最新最易懂)

    SpringBoot第十一集:整合Swagger3.0与RESTful接口整合返回值(2020最新最易懂) 一,整合Swagger3.0 随着Spring Boot.Spring Cloud等微服务的 ...

随机推荐

  1. mybatis进行mapper.xml测试的时候发生"必须为元素类型 “mapper” 声明属性 “namespace”

    1.Caused by Caused by: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 45; 必须为元素类型 " ...

  2. 《Head First 设计模式》:代理模式

    正文 一.定义 代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问. 要点: 代理模式为一个对象创建了代理对象,让代理对象控制对该对象的访问.被代理的对象可以是远程的对象.创建开销大的对象 ...

  3. Spring学习(十)--Spring的AOP

    1.Spring AOP拦截器 (1)设计原理 Spring AOP在通过JDK的Proxy或者CGLIB方式生成代理对象的时候,拦截器的相关信息就配置到代理对象中了. 1)如果使用JDK的Proxy ...

  4. Code Test(2)

    1110test T1:Inversion逆序数对1(inversion.cpp/in/out 1s 256M)给定N的值,要求找出一个N的全排列,这个全排列中,逆序数有M对.这样的结果会存在多个解, ...

  5. Python实现的数据结构与算法之基本搜索详解

    一.顺序搜索 顺序搜索 是最简单直观的搜索方法:从列表开头到末尾,逐个比较待搜索项与列表中的项,直到找到目标项(搜索成功)或者 超出搜索范围 (搜索失败). 根据列表中的项是否按顺序排列,可以将列表分 ...

  6. OneWire总线的Arduino库函数

    OneWire总线基本点 One-wire总线是DALLAS公司研制开发的一种协议,采用单根信号线,既传输时钟,又传输数据而且数据传输是双向的.它具有节省I/O 口线资源.结构简单.成本低廉.便于总线 ...

  7. 彻底理解红黑树及JavaJDK1.8TreeMap源码分析

    1. 定义 红黑树也是二叉查找树,我们知道,二叉查找树这一数据结构并不难,而红黑树之所以难是难在它是自平衡的二叉查找树,在进行插入和删除等可能会破坏树的平衡的操作时,需要重新自处理达到平衡状态.红黑树 ...

  8. 使用Jest快照测试api

    你知道什么很烦人吗?API不匹配. 有一天,后台开发人员在没有通知前端开发人员的情况下更改了其中一个api."我们认为dateCreated这个名字比created_at更好,"他 ...

  9. Java源码详解系列(十一)--Spring的使用和源码

    Spring 是一个一站式的 Java 框架,致力于提高我们项目开发的效率.通过 Spring,我们可以避免编写大量额外代码,更专注于我们的核心逻辑.目前,Spring 已经成为最受欢迎的 Java ...

  10. Java-JDK动态代理(AOP)使用及实现原理分析

    Java-JDK动态代理(AOP)使用及实现原理分析 第一章:代理的介绍 介绍:我们需要掌握的程度 动态代理(理解) 基于反射机制 掌握的程度: 1.什么是动态代理? 2.动态代理能够做什么? 后面我 ...