SpringBoot中的9个自带实用过滤器

首页 编程分享 PHP丨JAVA丨OTHER 正文

风象南 转载 编程分享 2025-05-10 22:13:54

简介 在SpringBoot应用中,过滤器(Filter)是处理HTTP请求和响应的重要组件,它们能在请求


在SpringBoot应用中,过滤器(Filter)是处理HTTP请求和响应的重要组件,它们能在请求到达控制器前或响应返回客户端前进行拦截处理。

SpringBoot自带了许多实用的过滤器,如字符编码、跨域请求、缓存控制等。

1. CharacterEncodingFilter - 字符编码过滤器

CharacterEncodingFilter是SpringBoot中最常用的过滤器之一,它确保HTTP请求和响应使用正确的字符编码,避免出现乱码问题。

功能和配置

在SpringBoot应用中,该过滤器默认已启用,使用UTF-8编码。你可以通过以下属性进行自定义配置:

# application.properties
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
server.servlet.encoding.enabled=true

手动配置示例

@Bean
public FilterRegistrationBean<CharacterEncodingFilter> characterEncodingFilter() {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF-8");
    filter.setForceEncoding(true);
    
    FilterRegistrationBean<CharacterEncodingFilter> registrationBean = new FilterRegistrationBean<>();
    registrationBean.setFilter(filter);
    registrationBean.addUrlPatterns("/*");
    registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return registrationBean;
}

实际应用:当你的应用需要处理多语言内容,特别是包含中文、日文、阿拉伯文等非ASCII字符时,此过滤器能确保数据在传输过程中不会出现乱码。

2. HiddenHttpMethodFilter - HTTP方法转换过滤器

HTML表单只支持GET和POST方法,但RESTful API通常需要PUT、DELETE等HTTP方法。HiddenHttpMethodFilter通过识别表单中的隐藏字段来模拟这些HTTP方法。

配置方式

# 默认是开启的,如需禁用可设置为false
spring.mvc.hiddenmethod.filter.enabled=true

使用示例

<form action="/users/123" method="post">
    <input type="hidden" name="_method" value="DELETE"/>
    <button type="submit">删除用户</button>
</form>

上述表单提交后,过滤器将把POST请求转换为DELETE请求,路由到对应的删除处理方法。

@DeleteMapping("/users/{id}")
public String deleteUser(@PathVariable Long id) {
    userService.deleteUser(id);
    return "redirect:/users";
}

实际应用:当你构建不使用JavaScript的传统Web应用,而又希望遵循RESTful设计原则时,这个过滤器非常有用。

3. FormContentFilter - 表单内容过滤器

FormContentFilter允许处理非POST请求(如PUT、PATCH等)中的表单数据,使这些请求的表单数据能像POST请求一样被解析。

配置方式

spring.mvc.formcontent.filter.enabled=true

实际应用场景

当客户端需要通过PUT请求更新资源,并以表单形式提交数据时,该过滤器能确保SpringMVC正确解析请求数据。

@PutMapping("/users/{id}")
public String updateUser(@PathVariable Long id, UserForm form) {
    // 没有FormContentFilter时,form对象的属性将无法被正确填充
    userService.updateUser(id, form);
    return "redirect:/users";
}

4. RequestContextFilter - 请求上下文过滤器

RequestContextFilter创建并维护一个RequestContext对象,使其在整个请求处理过程中可用,便于访问特定于请求的信息。

主要功能

  • 使Locale解析和主题解析可用于整个请求
  • 允许在任何地方获取当前请求的信息
  • 支持请求作用域的数据绑定

使用示例

@Component
public class RequestInfoService {
    
    public String getClientInfo() {
        ServletRequestAttributes attributes = 
            (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        
        return String.format("Client IP: %s, User-Agent: %s", 
                             request.getRemoteAddr(), 
                             request.getHeader("User-Agent"));
    }
}

实际应用:当你需要在非Controller组件(如Service层)中访问当前HTTP请求信息时,此过滤器提供的功能非常有用。

5. CorsFilter - 跨域资源共享过滤器

CorsFilter实现了跨域资源共享(CORS)规范,允许浏览器向不同域的服务器发送请求,解决同源策略的限制。

配置方式

@Bean
public CorsFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("https://example.com");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/api/**", config);
    
    return new CorsFilter(source);
}

也可通过属性配置:

spring.web.cors.allowed-origins=https://example.com
spring.web.cors.allowed-methods=GET,POST,PUT,DELETE
spring.web.cors.allowed-headers=Authorization,Content-Type
spring.web.cors.allow-credentials=true

实际应用:当你的前端应用和API部署在不同域名下时,如前端在example.com,API在api.example.com,CORS过滤器是必不可少的。

6. ShallowEtagHeaderFilter - ETag缓存过滤器

ShallowEtagHeaderFilter自动为HTTP响应添加ETag头信息,帮助客户端实现高效的缓存策略,减少不必要的网络传输。

原理与配置

此过滤器通过计算响应内容的哈希值生成ETag,当客户端再次请求相同资源时,可以通过比对ETag决定是否返回304(Not Modified)状态码。

@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
    FilterRegistrationBean<ShallowEtagHeaderFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(new ShallowEtagHeaderFilter());
    registration.addUrlPatterns("/api/*");
    registration.setName("shallowEtagHeaderFilter");
    return registration;
}

使用效果

  • 首次请求:服务器返回完整内容和ETag
  • 后续请求:客户端发送If-None-Match头,服务器比较ETag值
  • 内容未变:返回304状态码,无响应体
  • 内容已变:返回200状态码和新内容

实际应用:当你的应用提供大量静态内容或不频繁变化的API响应时,此过滤器能显著减少带宽使用并提高响应速度。

7. ForwardedHeaderFilter - 转发头信息过滤器

在使用负载均衡器或反向代理时,ForwardedHeaderFilter能处理转发的头信息,确保应用能正确识别客户端的原始信息。

处理的头信息

  • X-Forwarded-Host
  • X-Forwarded-Port
  • X-Forwarded-Proto
  • X-Forwarded-Prefix
  • X-Forwarded-For

配置示例

@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
    FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(new ForwardedHeaderFilter());
    registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return registration;
}

实际应用:当你的SpringBoot应用部署在Nginx或AWS ELB等反向代理后面时,此过滤器能确保生成的URL和重定向使用正确的协议、主机名和端口。

8. OrderedRequestContextFilter - 有序请求上下文过滤器

OrderedRequestContextFilterRequestContextFilter的扩展版本,实现了Ordered接口,使其在过滤器链中的执行顺序可以更精确控制。

与RequestContextFilter的区别

  • 实现了Ordered接口
  • 默认优先级为FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 10000
  • 在SpringBoot应用中替代了普通的RequestContextFilter

使用场景

当你有多个过滤器,且它们之间存在依赖关系时,OrderedRequestContextFilter能确保在正确的时机执行请求上下文初始化。

9. ResourceUrlEncodingFilter - 资源URL编码过滤器

ResourceUrlEncodingFilter主要用于处理静态资源的版本化URL,特别是在使用资源指纹或版本策略时。

功能介绍

  • 将资源路径转换为包含版本信息的URL
  • 支持内容哈希或固定版本号
  • 与ResourceUrlProvider协同工作

使用示例

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Bean
    public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
        return new ResourceUrlEncodingFilter();
    }
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600)
                .resourceChain(true)
                .addResolver(new VersionResourceResolver()
                        .addContentVersionStrategy("/**"));
    }
}

在模板中使用:

<!-- Thymeleaf -->
<link rel="stylesheet" th:href="@{/resources/css/main.css}"/>

<!-- 渲染后可能变为 -->
<link rel="stylesheet" href="/resources/css/main-d41d8cd98f00b204e9800998ecf8427e.css"/>

实际应用:当你需要实现高效的前端资源缓存策略,特别是在部署新版本时确保用户获取最新资源而不受浏览器缓存影响时,此过滤器非常有用。

总结

在实际项目中,根据应用需求选择合适的过滤器,并正确配置它们的执行顺序,将极大地提升应用的质量和开发效率。

转载链接:https://juejin.cn/post/7501903720378007615


Tags:


本篇评论 —— 揽流光,涤眉霜,清露烈酒一口话苍茫。


    声明:参照站内规则,不文明言论将会删除,谢谢合作。


      最新评论




ABOUT ME

Blogger:袅袅牧童 | Arkin

Ido:PHP攻城狮

WeChat:nnmutong

Email:nnmutong@icloud.com

标签云