在进行 Java web 开发的时候我们经常会使用到过滤器, 例如日志的记录, 权限的验证等功能. 以前使用 Spring MVC 的时候需要在 Web.xml 中配置过滤器, 现在使用 Spring Boot 的时候可免去配置文件, 但在最近的项目中按照网上的教程发现了一些错误的配置方式, 为此在这里进行总结.
使用 @Component 和 @Order 进行配置
这种配置方式是在我在这篇文章《How to Define a Spring Boot Filter?》 https://www.baeldung.com/spring-boot-add-filter 中看到的, 介绍了最基本的过滤器配置方式, 代码如下:
- @Component
- @Order(1)
- public class TransactionFilter implements Filter {
- @Override
- public void doFilter
- ServletRequest request,
- ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- HttpServletRequest req = (HttpServletRequest) request;
- LOG.info(
- "Starting a transaction for req : {}",
- req.getRequestURI());
- chain.doFilter(request, response);
- LOG.info(
- "Committing a transaction for req : {}",
- req.getRequestURI());
- }
- // other methods
- }
这种配置方式的劣势比较明显, 那就是不能对该过滤器配置配置需要过滤的 URL, 如果我们的过滤器需要过滤全部的链接, 用这种方式还是不错的.
使用 FilterRegistrationBean 手动进行注册
这种方式也是上述文章中介绍的一种方式, 它比较灵活, 缺点就是代码会多一些.
- @Bean
- public FilterRegistrationBean<RequestResponseLoggingFilter> loggingFilter(){
- FilterRegistrationBean<RequestResponseLoggingFilter> registrationBean
- = new FilterRegistrationBean<>();
- registrationBean.setFilter(new RequestResponseLoggingFilter());
- registrationBean.addUrlPatterns("/users/*");
- return registrationBean;
- }
使用 @WebFilter 和 @ServletComponentScan 两个注解进行配置
如果我们坚持想用注解去配置并且还想配置过滤的 URL, 那么用这两个注解可以实现, 配置方式很简单.
1. 在 Application 类上面加上 @ServletComponentScan 注解
- /**
- * @author xianglong.chen
- * @time 2019/2/22 上午 9:53
- */
- @SpringBootApplication
- @ServletComponentScan
- public class ServiceOneApplication {
- public static void main(String[] args) {
- SpringApplication.run(ServiceOneApplication.class, args);
- }
- }
2. 在 Filter 实现类上面添加 @WebFilter 注解, 配置 URL 与名称
- @WebFilter(urlPatterns = "/one/*", filterName = "helloFilter")
- public class OneFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- }
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- System.out.println("hello filter");
- filterChain.doFilter(servletRequest, servletResponse);
- }
- @Override
- public void destroy() {
- }
- }
上面提到的 @ServletComponentScan 注解的作用可以查看注释信息, 它的作用就是用来扫描 @WebFilter 注解的类的, 否则 @WebFilter 注解会不生效.
注意: 如果我们将上面的 OneFilter 上面加上了 @Component 注解后, Spring Boot 会注册两个过滤器.
- 2019-03-12 19:50:55.055 INFO 39447 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'helloFilter' to urls: [/one/*]
- 2019-03-12 19:50:55.055 INFO 39447 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'oneFilter' to: [/*]
可以看出我们用 @Component 注解过的类实现了 Filter 接口, Spring Boot 会将该类当做过滤器来使用.
No related posts.
来源: https://juejin.im/entry/5c879e7de51d4557a74b9c56