【Spring MVC 系列】Spring MVC 中 Filter 配置的 6 种方式,看看你了解哪些

简介: Filter 简介过滤器 Filter 在 Servlet 2.3 版本中被首次提出,唯一的作用就是过滤,它不仅可以过滤请求,还可以过滤响应,当请求到达 Servlet 容器,会先经过 Filter ,然后再交给 Servlet,之后 Filter 还可以对 Servlet 的响应进一步处理。并且多个 Filter 还能形成一个链。使用图示表达如下。

Filter 简介


过滤器 Filter 在 Servlet 2.3 版本中被首次提出,唯一的作用就是过滤,它不仅可以过滤请求,还可以过滤响应,当请求到达 Servlet 容器,会先经过 Filter ,然后再交给 Servlet,之后 Filter 还可以对 Servlet 的响应进一步处理。并且多个 Filter 还能形成一个链。使用图示表达如下。


image.png


Filter 的特性使得 Filter 可以对请求或响应进行包装,修改请求头、请求体、响应头、响应体。由于请求先到达 Filter,Filter 还可以做一些全局性的工作,例如日志打印、登录校验等等。


Filter 生命周期


Filter 作为一个接口,具体实现由用户负责,先看这个接口的定义。


public interface Filter {
    public void init(FilterConfig filterConfig) throws ServletException;
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
    public void destroy();
}


Filter 中定义了三个方法。


init:这是 Filter 的初始化方法,这个方法只会被容器调用一次,方法参数 FilterConfig 表示 Filter 的配置,可以利用这个参数读取初始化参数、ServletContext 等。

doFilter:这是 Filter 处理请求的核心方法,当请求到达时容器先回调这个方法处理请求,除了 request、response,这个方法还可以拿到过滤器链 FilterChain 对象,只有调用了 FilterChain#doFilter方法,容器才会使用过滤器链中的下一个过滤器处理请求,如果当前 Filter 已经是链中的最后一个,则会交给 Servlet 处理。

destroy:容器停止时回调的方法,用于做一些资源清理的工作。

Spring MVC 内置 Filter

针对一些通用的场景,Spring MVC 内置了一些 Filter,下面看常用的有哪些。


CharacterEncodingFilter:用于设置请求体、响应体字符集的过滤器,使用这个过滤器可以统一字符编码,避免出现乱码现象。

CorsFilter:这是用来处理跨域的过滤器,请求到达这个过滤器时,会根据配置添加跨域相关的响应头。


FormContentFilter:对于请求方法为PUT、PATCH、DELETE,内容类型为表单application/x-www-form-urlencoded的请求,请求体中的参数无法通过 ServletRequest#getParameter 方法读取,这个过滤器对请求已经包装,以便可以通过 #getParameter 方法读取参数。

Spring MVC 中的 Filter 配置

自从 Spring MVC 提供拦截器 HandlerInterceptor 之后,过滤器 Filter 的一部分功能已经可以搬到拦截器了,但有时还是会不可避免的使用到过滤器,如跨域处理。因此需要自定义过滤器 Filter,并配置到 Servlet 容器中,Spring MVC 在不同的阶段也提供了不同的配置方案,具体来说主要有 6 种。


1. 配置文件 web.xml 配置


Spring MVC 基于 Servlet 规范,Spring 早期,Servlet 和 Filter 配置方式与传统的 Java Web 项目并没有任何区别,需要在 web.xml 配置 Filter 清单。示例如下。


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>cors</filter-name>
        <filter-class>com.zzuhkp.mvc.CorsFilter</filter-class>
        <init-param>
            <param-name>allowedMethods</param-name>
            <param-value>GET,POST</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>cors</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>


2. @WebFilter 注解配置


Java 5 注解诞生后,Servlet 在 3.0 新引入了 @WebFilter 注解,用来替代 web.xml 文件中 Filter 的配置。Servlet 容器启动后会扫描类路径下的文件,遇到携带 @WebFilter 的注解后就会将这个类注册到容器中。因此在 Spring MVC 环境下也可以直接使用这个注解,和 xml 配置等同的注解配置如下。


@WebFilter(urlPatterns = "/*", initParams = {@WebInitParam(name = "allowedMethods", value = "GET,POST")})
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(request, response);
    }
}


3. ServletContainerInitializer 配置


除了常规的 Servlet 规范中的 xml 和 @WebFilter 配置方式, Servlet 3.0 规范还提供了一个 ServletContainerInitializer 接口,Servlet 容器启动后会扫描类路径,标注了 @HandlesTypes 注解的 ServletContainerInitializer 接口实现将会被回调。因此,在 Spring MVC 中也可以利用这个特性添加 Filter,具体代码如下。


@HandlesTypes({})
public class FilterInitializer implements ServletContainerInitializer {
    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
        FilterRegistration.Dynamic dynamic = ctx.addFilter("cors", new CorsFilter());
        dynamic.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
        dynamic.setInitParameter("allowedMethods","GET,POST");
    }
}


4. WebApplicationInitializer 配置


Spring 3.1 版本利用了上述 Servlet 规范中 ServletContainerInitializer 的特性,提供了这个接口的实现 SpringServletContainerInitializer,并在实现中回调了 Spring 提供的 WebApplicationInitializer 接口。因此,Spring MVC 环境也可以直接实现 WebApplicationInitializer 来手动配置 Filter。注意:只需要实现接口,无需特定配置,Servlet 容器会把这个类告诉 SpringServletContainerInitializer。示例代码如下。


public class CorsWebApplicationInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        FilterRegistration.Dynamic dynamic = servletContext.addFilter("cors", new CorsFilter());
        dynamic.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
        dynamic.setInitParameter("allowedMethods", "GET,POST");
    }
}


5. Spring Bean 配置


除了普通 Spring MVC 环境下的配置,Spring Boot 环境中,Spring Boot 1.4 及之后版本下还可以直接将 Filter 注册为 Bean,Filter Bean 将应用到所有的请求中。示例代码如下。


@Component
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(request, response);
    }
}


6. FilterRegistrationBean 配置


FilterRegistrationBean 同样是 Spring Boot 1.4 版本提出的一个新类型,这个类允许指定过滤的请求路径,将这个类配置为 Bean 即可。示例代码如下。


@Configuration
public class MvcConfig {
    @Bean
    public FilterRegistrationBean<CorsFilter> filterRegistrationBean() {
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter());
        bean.addUrlPatterns("/*");
        bean.addInitParameter("allowedMethods", "GET,POST");
        return bean;
    }
}


总结

本文主要对 Filter 的概念做了简单介绍,并介绍了几种 Spring MVC 内置的 Filter,最后介绍了 6 种在 Spring MVC 配置 Filter 的方式,其中 web.xml、@WebFilter、ServletContainerInitializer、WebApplicationInitializer 这 4 种配置方式适用于普通的 Spring MVC 环境,Filter Bean 配置、FilterRegistrationBean Bean 配置 适用于 Spring Boot 环境下的 Spring MVC,读者需要加以留意。


目录
相关文章
|
10天前
|
安全 Java API
深入解析 Spring Security 配置中的 CSRF 启用与 requestMatchers 报错问题
本文深入解析了Spring Security配置中CSRF启用与`requestMatchers`报错的常见问题。针对CSRF,指出默认已启用,无需调用`enable()`,只需移除`disable()`即可恢复。对于`requestMatchers`多路径匹配报错,分析了Spring Security 6.x中方法签名的变化,并提供了三种解决方案:分次调用、自定义匹配器及降级使用`antMatchers()`。最后提醒开发者关注版本兼容性,确保升级平稳过渡。
52 2
|
30天前
|
缓存 Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
本文介绍了在Spring Boot中配置Swagger2的方法。通过创建一个配置类,添加`@Configuration`和`@EnableSwagger2`注解,使用Docket对象定义API文档的详细信息,包括标题、描述、版本和包路径等。配置完成后,访问`localhost:8080/swagger-ui.html`即可查看接口文档。文中还提示了可能因浏览器缓存导致的问题及解决方法。
67 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
|
30天前
|
前端开发 Java 测试技术
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
本文介绍了 `@RequestParam` 注解的使用方法及其与 `@PathVariable` 的区别。`@RequestParam` 用于从请求中获取参数值(如 GET 请求的 URL 参数或 POST 请求的表单数据),而 `@PathVariable` 用于从 URL 模板中提取参数。文章通过示例代码详细说明了 `@RequestParam` 的常用属性,如 `required` 和 `defaultValue`,并展示了如何用实体类封装大量表单参数以简化处理流程。最后,结合 Postman 测试工具验证了接口的功能。
71 0
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
|
30天前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
80 0
|
30天前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestBody
`@RequestBody` 是 Spring 框架中的注解,用于将 HTTP 请求体中的 JSON 数据自动映射为 Java 对象。例如,前端通过 POST 请求发送包含 `username` 和 `password` 的 JSON 数据,后端可通过带有 `@RequestBody` 注解的方法参数接收并处理。此注解适用于传递复杂对象的场景,简化了数据解析过程。与表单提交不同,它主要用于接收 JSON 格式的实体数据。
92 0
|
30天前
|
前端开发 Java 微服务
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@PathVariable
`@PathVariable` 是 Spring Boot 中用于从 URL 中提取参数的注解,支持 RESTful 风格接口开发。例如,通过 `@GetMapping(&quot;/user/{id}&quot;)` 可以将 URL 中的 `{id}` 参数自动映射到方法参数中。若参数名不一致,可通过 `@PathVariable(&quot;自定义名&quot;)` 指定绑定关系。此外,还支持多参数占位符,如 `/user/{id}/{name}`,分别映射到方法中的多个参数。运行项目后,访问指定 URL 即可验证参数是否正确接收。
63 0
|
30天前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestMapping
@RequestMapping 是 Spring MVC 中用于请求地址映射的注解,可作用于类或方法上。类级别定义控制器父路径,方法级别进一步指定处理逻辑。常用属性包括 value(请求地址)、method(请求类型,如 GET/POST 等,默认 GET)和 produces(返回内容类型)。例如:`@RequestMapping(value = &quot;/test&quot;, produces = &quot;application/json; charset=UTF-8&quot;)`。此外,针对不同请求方式还有简化注解,如 @GetMapping、@PostMapping 等。
71 0
|
30天前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RestController
本文主要介绍 Spring Boot 中 MVC 开发常用的几个注解及其使用方式,包括 `@RestController`、`@RequestMapping`、`@PathVariable`、`@RequestParam` 和 `@RequestBody`。其中重点讲解了 `@RestController` 注解的构成与特点:它是 `@Controller` 和 `@ResponseBody` 的结合体,适用于返回 JSON 数据的场景。文章还指出,在需要模板渲染(如 Thymeleaf)而非前后端分离的情况下,应使用 `@Controller` 而非 `@RestController`
49 0
|
30天前
|
Java 数据库连接 数据库
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——MyBatis 介绍和配置
本文介绍了Spring Boot集成MyBatis的方法,重点讲解基于注解的方式。首先简述MyBatis作为持久层框架的特点,接着说明集成时的依赖导入,包括`mybatis-spring-boot-starter`和MySQL连接器。随后详细展示了`properties.yml`配置文件的内容,涵盖数据库连接、驼峰命名规范及Mapper文件路径等关键设置,帮助开发者快速上手Spring Boot与MyBatis的整合开发。
107 0
|
30天前
|
缓存 Java 应用服务中间件
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——依赖导入和Thymeleaf相关配置
在Spring Boot中使用Thymeleaf模板,需引入依赖`spring-boot-starter-thymeleaf`,并在HTML页面标签中声明`xmlns:th=&quot;http://www.thymeleaf.org&quot;`。此外,Thymeleaf默认开启页面缓存,开发时建议关闭缓存以实时查看更新效果,配置方式为`spring.thymeleaf.cache: false`。这可避免因缓存导致页面未及时刷新的问题。
41 0