1. 简介
在项目开发中,Filter(过滤器)是Servlet规范中的一项重要技术,充当请求与响应的"守门人"。它允许开发者在请求到达目标资源(如Controller, Servlet)之前或响应返回客户端之前,对请求和响应进行预处理与后处理。
核心功能:
- 请求拦截:如校验用户身份、设置字符编码、记录日志等。
- 响应修改:如压缩响应内容、添加自定义响应头。
应用场景:
- 安全防护:过滤非法请求,防止SQL注入或XSS攻击。
- 性能优化:通过缓存或压缩减少网络传输。
- 统一处理:集中管理跨域请求(CORS)、异常处理等。
Filter#doFilter方法实现链式调用,开发者可灵活组合多个Filter构建处理逻辑,是构建可扩展、可维护Web应用的关键组件。
在 Spring Boot 中,提供了许多实用的内置 Filter,开发者无需再自行编写,借助它们能更高效地构建 Web 应用。接下来,我们将详细介绍Spring Boot提供的非常强大的8个核心Filter。
2. 核心过滤器
2.1 字符编码Filter
CharacterEncodingFilter该过滤器应该不会陌生,这是非常早Spring就提供的一个过滤器,用来设置请求/响应字符编码。
@Bean
CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new CharacterEncodingFilter() ;
filter.setEncoding("UTF-8");
filter.setForceRequestEncoding(true);
filter.setForceResponseEncoding(true);
return filter ;
}
2.2 请求日志Filter
CommonsRequestLoggingFilter一个简单的请求日志过滤器,它会将请求 URI(以及可选的查询字符串)写入到 Commons Log(日志)中。
@Bean
CommonsRequestLoggingFilter commonsRequestLoggingFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter() ;
filter.setIncludeQueryString(true) ;
filter.setIncludeHeaders(true) ;
return filter ;
}
该过滤器提供了很多可配置项,如下:
最终效果如下:
注意,你还需要开启debug级别。
logging:
level:
'[org.springframework.web.filter]': debug
2.3 跨域Filter
CorsFilter用于处理 CORS 预检请求(pre-flight requests),并通过 CorsProcessor 拦截 CORS 简单请求和实际请求,同时根据通过提供的 CorsConfigurationSource 匹配的策略,更新响应(例如,添加 CORS 响应头)。
@Bean
CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(false);
config.addAllowedOrigin("*") ;
config.addAllowedHeader("*") ;
config.addAllowedMethod("*") ;
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
CorsFilter filter = new CorsFilter(source);
return filter;
}
2.4 表单数据过滤器
FormContentFilter用于解析 HTTP PUT、PATCH 和 DELETE 请求中的表单数据,并将其暴露为 Servlet 请求参数。默认情况下,Servlet 规范仅要求对 HTTP POST 请求执行此操作。
现在有如下接口:
@PutMapping("/put/param")
public String params(String name, Integer age) {
return name + "@" + age ;
}
通过postman访问该接口,输出结果如下:
没有获取到数据。接下来,配置如下过滤器
@Bean
FormContentFilter formContentFilter() {
FormContentFilter filter = new FormContentFilter() ;
return filter ;
}
再次访问上面的接口
成功获取值。
在Spring Boot中默认是已经注册了该过滤器的一个子类OrderedFormContentFilter。
2.5 弥补HTTP方法限制的桥梁
HiddenHttpMethodFilter 该过滤器用于解决浏览器仅支持GET/POST方法的限制,通过解析POST请求中的隐藏字段(如_method),将请求方法转换为PUT、DELETE、PATCH等,使后端可接收标准HTTP方法,助力RESTful API开发。
@Bean
HiddenHttpMethodFilter hiddenHttpMethodFilter() {
HiddenHttpMethodFilter filter = new HiddenHttpMethodFilter() ;
// 默认要求传的参数名:_method
filter.setMethodParam("_cm") ;
return filter ;
}
测试
定义如下Controller接口请求方法为patch,然后我们用post方式提交。
@PatchMapping("/patch")
public String patch(String name) {
return name ;
}
成功通过上面配置的过滤器映射到了patch上。该过滤器非常适合解决那些不允许get,post之外method的安全管理环境。
2.6 请求上下文线程绑定助手
RequestContextFilter 将请求上下文(如 Locale、请求属性等)绑定到当前线程,通过 LocaleContextHolder 和 RequestContextHolder 提供访问。
@Bean
RequestContextFilter requestContextFilter() {
RequestContextFilter filter = new RequestContextFilter() ;
// 子线程也可以获取上下文对象
filter.setThreadContextInheritable(true) ;
return filter ;
}
使用
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes() ;
HttpServletRequest request = attrs.getRequest() ;
2.7 解析请求路径
ServletRequestPathFilter 该过滤器用来解析并缓存当前请求的路径。
@Bean
ServletRequestPathFilter servletRequestPathFilter() {
ServletRequestPathFilter filter = new ServletRequestPathFilter() ;
return filter ;
}
使用
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes() ;
HttpServletRequest request = attrs.getRequest() ;
RequestPath requestPath = ServletRequestPathUtils.getParsedRequestPath(request) ;
// ...
你可以在任何其它bean组件中获取当前请求的完整uri。