SpringBoot第六集:整合监听器/过滤器和拦截器(2020最新最易懂)
在实际开发过程中,经常会碰见一些比如系统启动初始化信息、统计在线人数、在线用户数、过滤敏/高词汇、访问权限控制(URL级别)等业务需求。实现以上的功能,都会或多或少的用到过滤器
、监听器
、拦截器
。
一.SpringBoot整合过滤器Filter
过滤器Filter
,是Servlet
的的一个实用技术了。可以通过过滤器,对请求进行拦截处理。
1.编写Filter过滤器
- 编写普通Java类实现接口Filter。
- 使用注解@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 }
说明:@WebFilter
时Servlet3.0
新增的注解,原先实现过滤器,需要在web.xml
中进行配置,而现在通过此注解,启动启动时会自动扫描自动注册。 - 在启动类加入
@ServletComponentScan
注解
使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册。 - 开启启动类,访问测试,查看控制台结果
当注册多个过滤器时,无法指定执行顺序,早期使用
web.xml
配置过滤器时,是可指定执行顺序,但使用注解@WebFilter
时,没有顺序这个配置属性。通常情况下,如果对过滤器有特定顺序要求的,我们推荐采用原始方式配置,或者参考测试结果:执行顺序和类名字符排序有关。另外SpringBoot也为解决这个问题,单独提供了一个类FilterRegistrationBean,此类提供setOrder方法,可以为filter设置排序值,让Spring在注册Filter之前排序后再依次注册。
2.解决多过滤器执行顺序问题
- 编写两个/以上Filter,修改Filter的实现(去除注解@WebFilter即可,其他代码无需改动)
- 编写一个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 }
- 开启启动类,访问测试,查看控制台结果
说明:这种方式可以不使用注解@ServletComponentScan
二.SpringBoot整合监听器Listnner
Listnner是servlet规范中定义的一种特殊类。用于监听ServletContext、HttpSession和servletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件。用于在事件发生前、发生后做一些必要的处理。一般是获取在线人数等业务需求。
- 创建普通类实现监听器接口(比较多,我就不一一列出了)
本次案例:创建了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 }
- 在启动类加入
@ServletComponentScan
注解
使用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册。 - 开启启动类,访问测试,查看控制台结果
三.SpringBoot整合拦截器HandlerInterceptor
以上的过滤器、监听器都属于Servlet的API,我们在开发中过滤web请求时,还可以使用Spring
提供的拦截器(HandlerInterceptor
)进行更加精细的控制。
- 编写普通类实现接口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 }
- 编写普通类继承
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组件
- 开启启动类,访问测试,查看控制台结果
一张图理解过滤器,拦截器执行
目前互联网上很多大佬都有SpringBoot
系列教程,如有雷同,请多多包涵了。画图太费事了,图片来源于网络。