乐趣区

Spring-Boot项目中如何定制servletfilters

本文首发于个人网站:Spring Boot 项目中如何定制 servlet-filters

在实际的 web 应用程序中,经常需要在请求(request)外面增加包装用于:记录调用日志、排除有 XSS 威胁的字符、执行权限验证等等。除了上述提到的之外,Spring Boot 自动添加了 OrderedCharacterEncodingFilter 和 HiddenHttpMethodFilter,并且我们在自己的项目中还可以增加别的过滤器。

Spring Boot、Spring Web 和 Spring MVC 等其他框架,都提供了很多 servlet 过滤器可使用,我们需要在配置文件中定义这些过滤器为 bean 对象。现在假设我们的应用程序运行在一台负载均衡代理服务器后方,因此需要将代理服务器发来的请求包含的 IP 地址转换成真正的用户 IP。Tomcat 8 提供了对应的过滤器:RemoteIpFilter。通过将 RemoteFilter 这个过滤器加入过滤器调用链即可使用它。

实战

一般在写简单的例子时,不需要单独定义配置文件,只需要将对应的 bean 对象定义在 Application 类中即可。正式的项目中一般会有单独的 web 配置文件,我们在项目的com.test.bookpub(与 BookpubApplication.java 同级)下建立 WebConfiguration.java 文件,并用 @Configuration 注解修饰。

package com.test.bookpub;

import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebApplication {
    @Bean
    public RemoteIpFilter remoteIpFilter() {return new RemoteIpFilter();
    }
}

通过 mvn spring-boot:run 启动项目,可以在终端中看到如下的输出信息,证明 RemoteIPFilter 已经添加成功。

分析

项目的主类——BookPubApplication,可以看到由 @SpringBootApplication 注解修饰,这包含了 @ComponentScan、@Configuration 和 @EnableAutoConfiguration 注解。在 Spring Boot 的自动配置、Command-line Runner 一文中曾对这个三个注解做详细解释,@ComponentScan 让 Spring Boot 扫描到 WebConfiguration 类并把它加入到程序上下文中,因此,我们在 WebApplication 中定义的 Bean 就跟在 BookPubApplication 中定义一样。

方法 public RemoteIpFilter remoteIpFilter() { ...} 返回一个 RemoteIPFilter 类的 spring bean。当 Spring Boot 监测到有 javax.servlet.Filter 的 bean 时就会自动加入过滤器调用链。从上图中还可以看到,该 Spring Boot 项目一次加入了这几个过滤器:characterEncodingFilter(用于处理编码问题)、hiddenHttpMethodFilter(隐藏 HTTP 函数)、httpPutFormContentFilter、requestContextFilter(请求上下文),以及我们刚才自定义的 RemoteIPFilter。

所有过滤器的调用顺序跟添加的顺序相反,过滤器的实现是 责任链模式,具体的原理分析可以参考:责任链模式

Spring Boot 1.x 系列

  1. Spring Boot 的自动配置、Command-line-Runner
  2. 了解 Spring Boot 的自动配置
  3. Spring Boot 的 @PropertySource 注解在整合 Redis 中的使用
  4. Spring Boot 项目中如何定制 HTTP 消息转换器
  5. Spring Boot 整合 Mongodb 提供 Restful 接口
  6. Spring 中 bean 的 scope
  7. Spring Boot 项目中使用事件派发器模式
  8. Spring Boot 提供 RESTful 接口时的错误处理实践
  9. Spring Boot 实战之定制自己的 starter
  10. Spring Boot 项目如何同时支持 HTTP 和 HTTPS 协议
  11. 自定义的 Spring Boot starter 如何设置自动配置注解
  12. Spring Boot 项目中使用 Mockito
  13. 在 Spring Boot 项目中使用 Spock 测试框架
  14. Spring Boot 项目中如何定制拦截器
  15. Spring Boot 项目中如何定制 PropertyEditors
  16. Spring Boot 构建的 Web 项目如何在服务端校验表单输入
  17. Spring Boot 应用的健康监控

本号专注于后端技术、JVM 问题排查和优化、Java 面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。

退出移动版