如何在Spring Boot中添加筛选器类?

Spring Boot中是否有Filter类(用于web应用程序)的注释?也许@Filter ?

我想在我的项目中添加一个自定义过滤器。

Spring引导参考指南提到关于 FilterRegistrationBean,但我不确定如何使用它。

380106 次浏览

没有特殊的注释来表示servlet筛选器。你只需声明一个类型为Filter(或FilterRegistrationBean)的@Bean。一个例子(为所有响应添加自定义头)在Boot自己的EndpointWebMvcAutoConfiguration;

如果你只声明一个Filter,它将被应用到所有的请求。如果你还添加了FilterRegistrationBean,你可以额外指定要应用的单个servlet和url模式。

注意:

从Spring Boot 1.4开始,FilterRegistrationBean不再弃用,而是简单地将包从org.springframework.boot.context.embedded.FilterRegistrationBean移动到org.springframework.boot.web.servlet.FilterRegistrationBean

下面是一个在Spring Boot MVC应用程序中包含自定义过滤器的方法示例。确保在组件扫描中包含该包:

package com.dearheart.gtsc.filters;


import java.io.IOException;


import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;


import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;


@Component
public class XClacksOverhead implements Filter {


public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead";


@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {


HttpServletResponse response = (HttpServletResponse) res;
response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett");
chain.doFilter(req, res);
}


@Override
public void destroy() {}


@Override
public void init(FilterConfig arg0) throws ServletException {}


}

如果你想设置一个第三方过滤器,你可以使用FilterRegistrationBean

例如,等价的web . xml:

<filter>
<filter-name>SomeFilter</filter-name>
<filter-class>com.somecompany.SomeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SomeFilter</filter-name>
<url-pattern>/url/*</url-pattern>
<init-param>
<param-name>paramName</param-name>
<param-value>paramValue</param-value>
</init-param>
</filter-mapping>

这将是你的@Configuration文件中的两个bean:

@Bean
public FilterRegistrationBean someFilterRegistration() {


FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(someFilter());
registration.addUrlPatterns("/url/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("someFilter");
registration.setOrder(1);
return registration;
}


public Filter someFilter() {
return new SomeFilter();
}

以上是用Spring Boot 1.2.3测试的。

添加过滤器有三种方法,

  1. 用一个Spring构造型(如@Component)注释你的过滤器
  2. 在Spring @Configuration中用Filter类型注册一个@Bean
  3. 在Spring @Configuration中用FilterRegistrationBean类型注册一个@Bean

#1或#2都可以,如果你想让你的过滤器适用于所有请求而不自定义,否则使用#3。你不需要为#1指定组件扫描,只要你把你的过滤器类放在SpringApplication类的同一个或子包中。对于#3,只有当你想让Spring管理你的筛选器类,比如让它自动连接依赖时,才需要和#2一起使用。它工作得很好,为我新的我的过滤器,不需要任何依赖自动装配/注入。

虽然结合#2和#3效果很好,但我很惊讶它最终没有应用两次两个过滤器。我的猜测是,当Spring调用相同的方法来创建这两个bean时,它将这两个bean合并为一个。如果你想单独使用#3和authwiring,你可以AutowireCapableBeanFactory。举例如下:

private @Autowired AutowireCapableBeanFactory beanFactory;


@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
Filter myFilter = new MyFilter();
beanFactory.autowireBean(myFilter);
registration.setFilter(myFilter);
registration.addUrlPatterns("/myfilterpath/*");
return registration;
}

在Spring文档中,

嵌入式servlet容器-在应用程序中添加servlet,过滤器或监听器

要添加Servlet、过滤器或Servlet *监听器,请提供@Bean

例如:

@Bean
public Filter compressFilter() {
CompressingFilter compressFilter = new CompressingFilter();
return compressFilter;
}

将这个@Bean配置添加到你的@Configuration类中,过滤器将在启动时注册。

此外,您还可以使用类路径扫描添加servlet、过滤器和侦听器,

@WebServlet, @WebFilter和@WebListener注释类可以是 自动注册到嵌入的servlet容器 用@ServletComponentScan和注释@Configuration类 指定包含所需组件的包 登记。默认情况下,@ServletComponentScan将从包中扫描

下面是我的自定义Filter类的一个例子:

package com.dawson.controller.filter;


import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;


import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;




@Component
public class DawsonApiFilter extends GenericFilterBean {


@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
if (req.getHeader("x-dawson-nonce") == null || req.getHeader("x-dawson-signature") == null) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setContentType("application/json");
httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");
return;
}
chain.doFilter(request, response);
}
}

我将它添加到Spring Boot配置中,如下所示:

package com.dawson.configuration;


import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.dawson.controller.filter.DawsonApiFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;


@SpringBootApplication
public class ApplicationConfiguration {
@Bean
public FilterRegistrationBean dawsonApiFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new DawsonApiFilter());


// In case you want the filter to apply to specific URL patterns only
registration.addUrlPatterns("/dawson/*");
return registration;
}
}

如果您使用Spring Boot + Spring Security,则可以在安全配置中执行此操作。

在下面的例子中,我在UsernamePasswordAuthenticationFilter之前添加了一个自定义过滤器(参见所有默认的Spring Security过滤器及其顺序)。

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {


@Autowired FilterDependency filterDependency;


@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(
new MyFilter(filterDependency),
UsernamePasswordAuthenticationFilter.class);
}
}

还有筛选器类

class MyFilter extends OncePerRequestFilter  {
private final FilterDependency filterDependency;


public MyFilter(FilterDependency filterDependency) {
this.filterDependency = filterDependency;
}


@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {


// Filter
filterChain.doFilter(request, response);
}
}

你可以在实现javax.servlet.Filter的类上使用@WebFilter javax.servlet.annotation.WebFilter:

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
}

然后使用@ServletComponentScan注册。

使用@WebFilter注释,可以这样做:

@WebFilter(urlPatterns = {"/*" })
public class AuthenticationFilter implements Filter{


private static Logger logger = Logger.getLogger(AuthenticationFilter.class);


@Override
public void destroy() {
// TODO Auto-generated method stub


}


@Override
public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
throws IOException, ServletException {


logger.info("checking client id in filter");
HttpServletRequest request = (HttpServletRequest) arg0;
String clientId = request.getHeader("clientId");
if (StringUtils.isNotEmpty(clientId)) {
chain.doFilter(request, response);
} else {
logger.error("client id missing.");
}
}


@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub


}


}

过滤器主要用于日志文件中。它根据您在项目中使用的记录器而有所不同。

让我解释一下log4j2:

<Filters>
<!-- It prevents an error -->
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>


<!-- It prevents debug -->
<ThresholdFilter level="debug" onMatch="DENY" onMismatch="NEUTRAL" />


<!-- It allows all levels except debug/trace -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>

过滤器用于限制数据,我使用阈值过滤器进一步限制流中的数据级别。我提到了可以限制的水平。

如需进一步参考,请参阅log4j2 - Log4J Levels的级别顺序:ALL >跟踪比;调试比;信息在警告祝辞错误比;致命的祝辞从

更新:2022-05-29:

在Spring Boot 1.5.8中有两种简单的方法可以做到这一点。发布,不需要XML。

第一个方法:

如果你没有任何特定的URL模式,你可以像这样使用@Component(完整的代码和详细信息在这里https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/3_spring-boot-filter,看看README.txt开始):

@Component
public class ExampleFilter implements Filter {
...
}

第二种方式:

如果你想使用URL模式,你可以像这样使用@WebFilter(完整的代码和细节在这里https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/4_spring-boot-filter-urlpattern,看看README.txt开始):

@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter {
...
}

但是你也需要在你的@SpringBootApplication类中添加@ServletComponentScan注释:

@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
...
}

注意@Component是Spring的注释,而@WebFilter不是。@WebFilter是Servlet 3注释。

这两种方法,你只需要在pom.xml中有一个基本的Spring Boot依赖(不需要显式的Tomcat嵌入式jasper)

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>


<groupId>com.surasint.example</groupId>
<artifactId>spring-boot-04</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

第一种方法,如果Spring Boot中的Controller返回到JSP文件,请求将通过过滤器两次。

而在第二种方式中,请求将只通过筛选器一次。

我更喜欢第二种方式,因为它更类似于Servlet规范中的默认行为。

你也可以通过使用@WebFilter并实现Filter来创建过滤器。这样就行了。

@Configuration
public class AppInConfig
{
@Bean
@Order(1)
public FilterRegistrationBean aiFilterRegistration()
{
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new TrackingFilter());
registration.addUrlPatterns("/**");
registration.setOrder(1);
return registration;
}


@Bean(name = "TrackingFilter")
public Filter TrackingFilter()
{
return new TrackingFilter();
}
}

首先,将@ServletComponentScan添加到SpringBootApplication类中。

@ServletComponentScan
public class Application {

其次,创建一个扩展filter或第三方过滤器类的过滤器文件,并将@WebFilter添加到该文件中,如下所示:

@Order(1) //optional
@WebFilter(filterName = "XXXFilter", urlPatterns = "/*",
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD},
initParams = {@WebInitParam(name = "confPath", value = "classpath:/xxx.xml")})
public class XXXFilter extends Filter{

我在这里看到了很多答案,但我没有尝试任何一个。我刚刚创建了如下代码所示的过滤器。

import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;


@WebFilter(urlPatterns = "/Admin")
@Configuration
public class AdminFilter 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("happened");


}


@Override
public void destroy() {


}
}

我让剩下的Spring Boot应用程序保持原样。

这是一个建议而不是答案,但如果你在你的web应用程序中使用Spring MVC,最好使用Spring HandlerInterceptor而不是Filter。

它可以做同样的工作,但是

  • 可以使用ModelAndView吗
  • 它的方法可以在请求处理之前和之后调用,或者在请求完成之后调用。
  • 它很容易测试

1. 实现HandlerInterceptor接口,并向类中添加@Component注释

@Component
public class SecurityInterceptor implements HandlerInterceptor {


private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);


@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
request.getSession(true);
if(isLoggedIn(request))
return true;


response.getWriter().write("{\"loggedIn\":false}");
return false;
}


private boolean isLoggedIn(HttpServletRequest request) {
try {
UserSession userSession = (UserSession) request.getSession(true).getAttribute("userSession");
return userSession != null && userSession.isLoggedIn();
} catch(IllegalStateException ex) {
return false;
}
}


@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {


}


@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {


}
}

2. 配置拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {


private HandlerInterceptor securityInterceptor;


@Autowired
public void setSecurityInterceptor(HandlerInterceptor securityInterceptor) {
this.securityInterceptor = securityInterceptor;
}


@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/logout");
}


}

使用:

@WebFilter(urlPatterns="/*")
public class XSSFilter implements Filter {


private static final org.apache.log4j.Logger LOGGER = LogManager.getLogger(XSSFilter.class);


@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("Initiating XSSFilter... ");
}


@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpRequestWrapper requestWrapper = new HttpRequestWrapper(req);
chain.doFilter(requestWrapper, response);
}


@Override
public void destroy() {
LOGGER.info("Destroying XSSFilter... ");
}


}

你需要实现Filter,并且它需要用@WebFilter(urlPatterns="/*")注释。

在Application类或Configuration类中,你需要添加@ServletComponentScan。通过此操作,您的筛选器将被注册。

我看到答案是瓦西里·科马罗夫。下面是一个类似的方法,但使用抽象HandlerInterceptorAdapter类而不是HandlerInterceptor

这里有一个例子……

@Component
public class CustomInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
}
}


@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {


@Autowired
private CustomInterceptor customInterceptor ;


@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor );
}


}

众所周知,Spring Boot是开发web应用程序或独立应用程序的一种极好的方式,具有最低的配置和独立的设置。

这就是我如何在Spring Boot应用程序中实现web过滤器开发的

我的SpringBootApp规格:

Spring Boot version: 2.0.4发布
Java版本:8.0
Servlet规范:Servlet 3.0(必选且重要)

我以以下方式声明了我的web过滤器,遵循Servlet规范3.0

Enter image description here

这是定义过滤器的编程方法,用于替换基于__abc1的定义。

“@Webfilter"注释将在部署期间由容器处理。它所在的Filter类将根据配置创建,并应用于URL模式javax.servlet.Servlets和javax.servlet.DispatcherTypes。

完全避免Web.xml,实现“可部署”;应用:

要将SpringBoot应用程序部署为“Traditional war”,应用程序类应该扩展SpringBootServletInitializer。

注意:

SpringBootServletInitializer是一个“编程实现”。web . xml的定义,参考Servlet 3.0+规范,它需要WebApplicationInitializer的实现。

因此,SpringBootApplication不需要"web.xml"作为它的应用程序类(在扩展SpringBootServletInitializer之后)。它扫描

  • @WebFilter,
  • @WebListener和
  • @WebServlet。

注释@ServletComponentScan

这个注释允许扫描带有@WebFilter, @WebListener和@WebServlet注释的web组件的基本包。

由于嵌入式容器不支持@WebServlet、@WebFilter和@WebListener注解,Spring Boot在很大程度上依赖于嵌入式容器,引入了这个新的注解@ServletComponentScan来支持一些使用这三种注解的依赖JAR文件。

扫描只在使用嵌入式Servlet容器时执行。

下面是我的Spring Boot应用程序类定义:

Enter image description here

自定义Servlet初始化器:

这里:我定义了一个自定义类: "ServletInitializer"它扩展了Class: SpringBootServletInitializer。

如前所述,SpringBootServletInitializer负责扫描注释:

  • @WebFilter,
  • @WebListener和
  • @WebServlet。

因此Spring Boot应用程序类应该这样做

  • 要么扩展类:SpringBootServletInitializer
  • 扩展扩展该类的自定义类:SpringBootServletInitializer

Enter image description here

过滤器,顾名思义,用于对资源的请求或资源的响应执行过滤,或同时对两者执行过滤。Spring Boot提供了一些选项来在Spring Boot应用程序中注册自定义过滤器。让我们看看不同的选项。

1. 定义Spring Boot过滤器和调用顺序

在Spring Boot中实现过滤器接口来创建一个新的过滤器。

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomFilter implements Filter {


private static final Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);


@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating Custom filter ##########");
}


@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {


HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;


LOGGER.info("Logging Request  {} : {}", request.getMethod(), request.getRequestURI());


// Call next filter in the filter chain
filterChain.doFilter(request, response);


LOGGER.info("Logging Response :{}", response.getContentType());
}


@Override
public void destroy() {
// TODO: 7/4/2018
}
}

让我们快速看一下上面代码中的一些要点

  • < >强@ component < / >强注释注册的过滤器。

  • 为了以正确的顺序触发过滤器,我们需要使用< >强@Order < / >强注释。

     @Component
    @Order(1)
    public class CustomFirstFilter implements Filter {
    
    
    }
    
    
    @Component
    @Order(2)
    public class CustomSecondFilter implements Filter {
    
    
    }
    

在上面的代码中,CustomFirstFilter将在CustomSecondFilter之前运行。

数字越低,优先级越高

2. URL模式

如果基于约定的映射不够灵活,我们可以使用< >强FilterRegistrationBean < / >强来完全控制应用程序。在这里,不要为过滤器类使用< >强@ component < / >强注释,而是使用< >强FilterRegistrationBean < / >强注册过滤器。

public class CustomURLFilter implements Filter {


private static final Logger LOGGER = LoggerFactory.getLogger(CustomURLFilter.class);


@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating CustomURLFilter filter ##########");
}


@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {


HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;


LOGGER.info("This Filter is only called when request is mapped for /customer resource");


// Call the next filter in the filter chain
filterChain.doFilter(request, response);
}


@Override
public void destroy() {


}
}

使用< >强FilterRegistrationBean < / >强注册自定义过滤器。

@Configuration
public class AppConfig {


@Bean
public FilterRegistrationBean < CustomURLFilter > filterRegistrationBean() {
FilterRegistrationBean < CustomURLFilter > registrationBean = new FilterRegistrationBean();
CustomURLFilter customURLFilter = new CustomURLFilter();


registrationBean.setFilter(customURLFilter);
registrationBean.addUrlPatterns("/greeting/*");
registrationBean.setOrder(2); // Set precedence
return registrationBean;
}
}

此过滤器还将帮助您允许跨源访问

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {


public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {


HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "20000");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");


if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}




public void destroy() {}


@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub


}


}

我们大概有四个不同的使用Spring注册一个过滤器选项。

首先,我们可以创建一个实现过滤器或扩展HttpFilter的Spring bean:

@Component
public class MyFilter extends HttpFilter {


@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Implementation details...


chain.doFilter(request, response);
}
}

其次,我们可以创建一个扩展GenericFilterBean的Spring bean:

@Component
public class MyFilter extends GenericFilterBean {


@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
//Implementation details...


chain.doFilter(currentRequest, servletResponse);
}
}

我们也可以使用FilterRegistrationBean类:

@Configuration
public class FilterConfiguration {


private final MyFilter myFilter;


@Autowired
public FilterConfiguration(MyFilter myFilter) {
this.myFilter = myFilter;
}


@Bean
public FilterRegistrationBean<MyFilter> myFilterRegistration() {
FilterRegistrationBean<DateLoggingFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(myFilter);
filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
filterRegistrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 1);
return filterRegistrationBean;
}
}

最后,我们可以使用@WebFilter注释和@ServletComponentScan:

@WebFilter(urlPatterns = "/*", dispatcherTypes = {DispatcherType.REQUEST})
public class MyFilter extends HttpFilter {


@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Implementation details...


chain.doFilter(request, response);
}
}

你主要需要两样东西:

  • @ServletComponentScan添加到你的主类

  • 你可以在里面添加一个名为filter的包。你创建了一个Filter类,它有以下内容:

      @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class RequestFilter implements Filter {
    
    
    // whatever field you have
    
    
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest request = (HttpServletRequest) req;
    
    
    // Whatever implementation you want
    
    
    try {
    chain.doFilter(req, res);
    } catch(Exception e) {
    e.printStackTrace();
    }
    }
    
    
    public void init(FilterConfig filterConfig) {
    }
    
    
    public void destroy() {
    }
    }
    

步骤1:通过实现过滤器接口创建过滤器组件。

@Component
public class PerformanceFilter implements Filter {


@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {


...
...
}


}

步骤2:使用FilterRegistrationBean将这个过滤器设置为URI模式。

@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<PerformanceFilter> perfFilter() {
FilterRegistrationBean<PerformanceFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new PerformanceFilter());
registration.addUrlPatterns("/*");
return registration;
}
}

你可以参考这个链接来获得一个完整的应用程序。

对于Spring Boot在我所做的任何配置类:

@Bean
public OncePerRequestFilter myFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
AuthUser authUser = SecurityUtil.safeGet(); // applied after secutiry filters
...
filterChain.doFilter(request, response);
}
};
}

这就是全部,不需要任何注册。另见什么是OncePerRequestFilter?

用一个Spring原型(如@Component)注释你的过滤器。在Spring @Configuration中注册一个Filter类型的@Bean。在Spring @Configuration中用FilterRegistrationBean类型注册一个@Bean。