How to Define a Spring Boot Filter? – 如何定义一个Spring Boot过滤器?

最后修改: 2018年 4月 30日

中文/混合/英文(键盘快捷键:t)

 1. Overview

1.概述

In this quick tutorial, we’ll explore how to define custom filters and specify their invocation order with the help of Spring Boot.

在这个快速教程中,我们将探讨如何在Spring Boot的帮助下定义自定义过滤器并指定其调用顺序。

2. Defining Filters and the Invocation Order

2.定义过滤器和调用顺序

Let’s start by creating two filters:

让我们从创建两个过滤器开始。

  1. TransactionFilter – to start and commit transactions
  2. RequestResponseLoggingFilter – to log requests and responses

In order to create a filter, we simply need to implement the Filter interface:

为了创建一个过滤器,我们只需要实现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 
}

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

In order for Spring to recognize a filter, we need to define it as a bean with the @Component annotation.

为了让Spring识别一个过滤器,我们需要用@Component注解把它定义为一个bean。

Moreover, to have the filters fire in the right order, we need to use the @Order annotation.

此外,为了让过滤器以正确的顺序启动,我们需要使用@Order注解。

2.1. Filter With URL Pattern

2.1.用URL模式过滤

In the example above, our filters are registered by default for all of the URLs in our application. However, we may sometimes want a filter to only apply to certain URL patterns.

在上面的例子中,我们的过滤器默认是为我们应用程序中的所有URL注册的。然而,我们有时可能希望一个过滤器只适用于某些URL模式。

In this case, we have to remove the @Component annotation from the filter class definition and register the filter using a FilterRegistrationBean:

在这种情况下,我们必须从过滤器类的定义中删除@Component注解,并使用FilterRegistrationBean来注册过滤器:

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

Note, that in this case we need to explicitly set the order using a setOrder() method.

注意,在这种情况下,我们需要使用setOrder()方法明确地设置顺序。

Now the filter will only apply for paths that match the /users/* pattern.

现在,过滤器将只适用于符合/users/*模式的路径。

To set URL patterns for the filter, we can use the addUrlPatterns() or setUrlPatterns() methods.

要为过滤器设置URL模式,我们可以使用addUrlPatterns()setUrlPatterns()方法。

3. A Quick Example

3.一个快速的例子

Now let’s create a simple endpoint and send an HTTP request to it:

现在让我们创建一个简单的端点,并向它发送一个HTTP请求。

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

The application logs on hitting this API are :

点击这个API的应用日志是 。

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

This confirms the filters are invoked in the desired order.

这就确认了过滤器是按所需的顺序调用的。

4. Conclusion

4.总结

In this brief article, we summarized how to define custom filters in a Spring Boot webapp.

在这篇简短的文章中,我们总结了如何在Spring Boot webapp中定义自定义过滤器。

As always, the code snippets can be found over on GitHub.

像往常一样,代码片段可以在GitHub上找到over