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这个过滤器加入过滤器调用链即可使用它。

How Do

一般在写简单的例子时,不需要单独定义配置文件,只需要将对应的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已经添加成功。


RemoteIPFilter

分析

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

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

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



    相关文章
    |
    13天前
    |
    缓存 NoSQL Java
    Springboot自定义注解+aop实现redis自动清除缓存功能
    通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
    37 2
    |
    4月前
    |
    运维 Java 关系型数据库
    Spring运维之boot项目bean属性的绑定读取与校验
    Spring运维之boot项目bean属性的绑定读取与校验
    50 2
    |
    4月前
    |
    存储 运维 Java
    Spring运维之boot项目开发关键之日志操作以及用文件记录日志
    Spring运维之boot项目开发关键之日志操作以及用文件记录日志
    56 2
    |
    4月前
    |
    Java Maven
    springboot项目打jar包后,如何部署到服务器
    springboot项目打jar包后,如何部署到服务器
    348 1
    |
    4月前
    |
    XML 运维 Java
    Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
    Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
    45 1
    |
    3月前
    |
    前端开发 Java 应用服务中间件
    Spring Boot 2.x 嵌入式 Servlet 容器
    Spring Boot使用内嵌Tomcat,默认端口8080,可通过`application.properties`配置端口、上下文路径等。配置方式有两种:1) 直接在配置文件中添加`server.port`和`server.servlet.context-path`;2) 创建`WebServerFactoryCustomizer` Bean来自定义配置,如设置端口`factory.setPort(8083)`,这种方式优先级更高。
    |
    4月前
    |
    API
    获得servlet相关API,获得请求头和cookie-spring23
    获得servlet相关API,获得请求头和cookie-spring23
    |
    4月前
    springboot2.4.5使用pagehelper分页插件
    springboot2.4.5使用pagehelper分页插件
    124 0
    |
    4月前
    |
    缓存 运维 Java
    Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
    Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
    41 0
    |
    5月前
    |
    安全 Java 应用服务中间件
    江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
    江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
    64 0
    江帅帅:Spring Boot 底层级探索系列 03 - 简单配置