Spring Boot 内置过滤器用法详解

内容分享3周前发布
0 0 0

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 方法扩展、跨域支持、上下文绑定、安全认证 等常见场景。同时,开发者也可以通过 自定义过滤器 精细化控制请求处理链。

掌握过滤器的用法,你就能:

  1. 统一请求编码
  2. 支持 RESTful 请求(PUT/DELETE 表单)
  3. 处理跨域请求
  4. 记录请求日志、监控性能
  5. 实现安全认证与授权
  6. 在 WebFlux 中进行响应式扩展

合理利用过滤器,能协助你在 HTTP 请求链路上 既利用 Spring Boot 的自动化,又能灵活扩展,提升系统的健壮性和可维护性


Spring Boot 内置过滤器用法详解

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...