Spring Boot 内置过滤器用法详解
在 Spring Boot Web 应用中,过滤器(Filter) 是 HTTP 请求处理链上的重大组成部分。Spring Boot 不仅提供了多种内置过滤器,还支持灵活的自定义扩展。合理使用过滤器,能够实现请求编码、跨域处理、日志记录、安全认证等功能。
本文将从 内置过滤器清单 → 常见用法 → 自定义扩展 → 顺序控制 → 高级技巧 全面解析。
1. Spring Boot 内置过滤器清单
Spring Boot 会根据依赖自动注册一些过滤器,以下是常见的内置过滤器:
|
过滤器 |
作用 |
默认状态 |
|
CharacterEncodingFilter |
设置统一编码(默认 UTF-8) |
✅ |
|
HiddenHttpMethodFilter |
支持 _method 参数扩展 PUT/DELETE |
✅(可关闭) |
|
FormContentFilter |
允许 PUT/DELETE 请求读取表单数据 |
✅(可关闭) |
|
CorsFilter |
处理跨域请求 |
❌(需手动配置或全局 CORS 配置) |
|
RequestContextFilter |
将请求绑定到 RequestContextHolder,便于在 Service 层获取 |
✅ |
|
OrderedRequestContextFilter |
确保 RequestContextFilter 按顺序执行 |
✅ |
|
WebAsyncManagerIntegrationFilter |
集成异步请求的上下文(如 Callable/DeferredResult) |
Spring Security 引入 |
|
SecurityContextPersistenceFilter |
管理 SecurityContext(认证信息) |
Spring Security 引入 |
|
CsrfFilter |
防止跨站请求伪造 |
Spring Security 引入 |
|
LogoutFilter |
处理用户退出逻辑 |
Spring Security 引入 |
2. 常用内置过滤器示例
2.1 CharacterEncodingFilter
统一设置请求和响应的字符编码。
@Configuration
public class FilterConfig {
@Bean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
return filter;
}
}
2.2 HiddenHttpMethodFilter
允许使用 _method 字段模拟 PUT、DELETE 等请求。
<form method="post" action="/users/1">
<input type="hidden" name="_method" value="put">
<input type="submit" value="更新用户">
</form>
Controller 里即可用 @PutMapping(“/users/{id}”) 接收。
2.3 FormContentFilter
使 PUT / DELETE 也能解析表单数据。
spring.mvc.formcontent.filter.enabled=true
2.4 CorsFilter
处理跨域请求的过滤器。
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
2.5 RequestContextFilter
将 HttpServletRequest 与当前线程绑定,便于在 Service、异步任务中获取请求上下文。
3. 自定义过滤器
Spring Boot 允许我们实现 Filter 接口,插入自定义逻辑。
@Component
public class CustomFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(CustomFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
logger.info("请求URL: {}", req.getRequestURL());
chain.doFilter(request, response);
logger.info("响应状态: {}", ((HttpServletResponse) response).getStatus());
}
}
4. 过滤器顺序控制
通过 FilterRegistrationBean 控制执行顺序:
@Configuration
public class FilterOrderConfig {
@Bean
public FilterRegistrationBean<CustomFilter> customFilterRegistration() {
FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new CustomFilter());
registration.addUrlPatterns("/*");
registration.setOrder(1); // 越小优先级越高
return registration;
}
}
⚠️ 注意:Spring Security 的过滤器链一般优先级较高,若有安全相关逻辑需要明确顺序。
5. 基于注解的配置
使用 @WebFilter 声明过滤器:
@WebFilter(urlPatterns = "/*", filterName = "annotationFilter")
public class AnnotationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
}
启动类需加 @ServletComponentScan:
@SpringBootApplication
@ServletComponentScan
public class Application {}
6. 禁用特定过滤器
在 application.properties 中禁用默认过滤器:
# 禁用 HiddenHttpMethodFilter
spring.mvc.hiddenmethod.filter.enabled=false
# 禁用 FormContentFilter
spring.mvc.formcontent.filter.enabled=false
7. 过滤器 vs 拦截器
许多人容易混淆 Filter 和 Interceptor,区别如下:
|
对比项 |
Filter |
Interceptor |
|
规范 |
Servlet 规范,容器级别 |
Spring MVC 提供,Spring 容器级别 |
|
拦截范围 |
所有 Servlet 请求(静态资源也会拦截) |
仅拦截 Controller 请求 |
|
生命周期 |
应用启动时创建,销毁时释放 |
随 Spring Bean 生命周期 |
|
使用场景 |
编码、跨域、安全、日志 |
登录验证、权限校验、业务逻辑前后处理 |
8. 性能优化与最佳实践
- 避免耗时操作:过滤器应尽量轻量,复杂逻辑放到 Service 层。
- 日志提议异步写入:避免同步 I/O 阻塞请求。
- 推荐使用 OncePerRequestFilter:避免一个请求被多次执行过滤器。
@Component
public class OnceLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
long start = System.nanoTime();
filterChain.doFilter(request, response);
long cost = (System.nanoTime() - start) / 1_000_000;
logger.info("耗时:{} ms - {}", cost, request.getRequestURI());
}
}
9. WebFlux 下的过滤器
如果使用的是 Spring WebFlux(响应式编程),则使用 WebFilter 而不是 Servlet Filter:
@Component
public class ReactiveLoggingFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
long start = System.currentTimeMillis();
return chain.filter(exchange)
.doFinally(signal -> {
long cost = System.currentTimeMillis() - start;
System.out.println("请求耗时: " + cost + "ms");
});
}
}
10. 实战案例:请求日志过滤器
@Component
public class RequestLoggingFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(RequestLoggingFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
long startTime = System.currentTimeMillis();
logger.info("开始处理: {} {}", req.getMethod(), req.getRequestURI());
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - startTime;
logger.info("请求完成: {} {} - 状态:{} - 耗时:{}ms",
req.getMethod(), req.getRequestURI(), res.getStatus(), duration);
}
}
总结
Spring Boot 提供了功能强劲的内置过滤器,涵盖了 编码处理、HTTP 方法扩展、跨域支持、上下文绑定、安全认证 等常见场景。同时,开发者也可以通过 自定义过滤器 精细化控制请求处理链。
掌握过滤器的用法,你就能:
- 统一请求编码
- 支持 RESTful 请求(PUT/DELETE 表单)
- 处理跨域请求
- 记录请求日志、监控性能
- 实现安全认证与授权
- 在 WebFlux 中进行响应式扩展
合理利用过滤器,能协助你在 HTTP 请求链路上 既利用 Spring Boot 的自动化,又能灵活扩展,提升系统的健壮性和可维护性。



