Spring Boot - 如何定义Filter

标签:翻译 Spring Boot
原文地址: https://www.baeldung.com/spring-boot-add-filter

更多Spring实战内容,请参考Spring - 实战指南

1. 概述

这里我们通过一个简单的例子,快速学习一下如何在Spring Boot中自定义一个Filter

2. 定义Filters和顺序

让我们创建两个Filter:

  • TransactionFilter: start并commit一个事务
  • RequestResponseLoggingFilter: 将request和response输出到日志

TransactionFilter.java

@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 
}

RequestResponseLoggingFilter.java

@Component
@Order(2)
public class RequestResponseLoggingFilter implements Filter {
 
    @Override
    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {
  
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        LOG.info(
          "Logging Request  {} : {}", req.getMethod(), 
          req.getRequestURI());
        chain.doFilter(request, response);
        LOG.info(
          "Logging Response :{}", 
          res.getContentType());
    }
 
    // other methods
}

为了让Spring能识别Filter,我们需要添加@Component注解

为了定义Filter的顺序,我们需要@Order注解

译者注:
@Order注解的值越小,表示优先级越高,也就是说优先执行

2. Filter过滤特定URL

上面的Filter会过滤所有的URL。有时我们只需要过滤特定前缀的URL。

这种情况下,我们就不能用@Component注解了。需要手动将Filter注册到FilterRegistrationBean

@Bean
public FilterRegistrationBean loggingFilter(){
    FilterRegistrationBean registrationBean 
      = new FilterRegistrationBean<>();
         
    registrationBean.setFilter(new RequestResponseLoggingFilter());
    registrationBean.addUrlPatterns("/users/*");
         
    return registrationBean;    
}

上面的例子中,RequestResponseLoggingFilter只会过滤能匹配/users/*的URL

这个功能是通过addUrlPatterns()或者setUrlPatterns()方法实现的。

3. 一个简单的例子

让我们写一个简单的例子,看看Filter是否生效:

@RestController
@RequestMapping("/users")
public class UserController {
     
    @GetMapping()
    public List getAllUsers() {
        // ...
    }
}

输出日志:

23:54:38 INFO  com.spring.demo.TransactionFilter - Starting Transaction for req :/users
23:54:38 INFO  c.s.d.RequestResponseLoggingFilter - Logging Request  GET : /users
...
23:54:38 INFO  c.s.d.RequestResponseLoggingFilter - Logging Response :application/json;charset=UTF-8
23:54:38 INFO  com.spring.demo.TransactionFilter - Committing Transaction for req :/users

上面的结果说明,Filter生效了,并且顺序也是符合我们预期的。

你可能感兴趣的:(Spring Boot - 如何定义Filter)