OncePerRequestFilter
是 Spring 框架提供的一个非常有用的过滤器,它的主要作用是在每次请求中只执行一次过滤逻辑。这种特性使得它在实现一些通用的请求处理逻辑时非常方便,特别是在需要进行身份验证、日志记录或者请求预处理等场景中。
OncePerRequestFilter 的核心概念
OncePerRequestFilter
继承自 GenericFilterBean
,它使用的设计模式是模板方法模式。在每个请求处理的生命周期中,该过滤器会确保某个特定的逻辑只会执行一次。具体来说,doFilterInternal
方法会在请求到达 servlet 前执行,而 doFilter
方法则确保了每次请求只处理一次。
代码示例
让我们通过一个示例来加深对 OncePerRequestFilter
的理解。在这个例子中,我们将实现一个简单的身份验证过滤器,用于检查每个请求是否携带有效的身份验证令牌。
首先,我们需要引入 Spring 相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
下面是我们的自定义过滤器类:
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 获取请求头中的认证令牌
String authToken = request.getHeader("Authorization");
// 这里简单判断令牌是否有效
if (authToken == null || !authToken.equals("VALID_TOKEN")) {
// 返回401未授权
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
return;
}
// 调用下一个过滤器或处理器
filterChain.doFilter(request, response);
}
}
在 Spring 配置中注册过滤器
完成过滤器的定义后,我们需要在 Spring 配置中注册它。可以通过继承 WebSecurityConfigurerAdapter
类或者在 Spring Boot 的主类上使用 @Bean
注解进行注册。以下是使用 @Bean
注解的示例:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.filter.DelegatingFilterProxy;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public AuthenticationFilter authenticationFilter() {
return new AuthenticationFilter();
}
}
总结
OncePerRequestFilter
是一个非常强大的工具,能够帮助开发者实现请求级别的过滤逻辑而无需担心逻辑多次执行的问题。通过自定义 doFilterInternal
方法,开发者可以轻松地对每个请求进行验证、日志记录等处理,提升了代码的重用性和可维护性。
在实际工作中,我们可以将 OncePerRequestFilter
和 Spring 的其他特性结合使用,如安全框架(Spring Security)来实现更为复杂的认证和授权逻辑,为应用程序提供强大的安全保障。