spring-tutorial/docs/01.Java/13.框架/01.Spring/03.SpringWeb/04.Spring过滤器.md

4.9 KiB
Raw Permalink Blame History

title date categories tags permalink
Spring MVC 之过滤器 2023-02-14 17:44:09
Java
框架
Spring
SpringWeb
Java
框架
Spring
Web
Filter
/pages/4a164d/

Spring MVC 之过滤器

spring-web 模块提供了一些有用的 Filter

表单内容过滤器

浏览器只能通过 HTTP GET 或 HTTP POST 提交表单数据,但非浏览器客户端也可以使用 HTTP PUT、PATCH 和 DELETE。 Servlet API 需要 ServletRequest.getParameter*() 系列方法来支持仅对 HTTP POST 的表单字段访问。

spring-web 模块提供了 FormContentFilter 来拦截内容类型为 applicationx-www-form-urlencoded 的 HTTP PUT、PATCH、DELETE 请求,从请求体中读取表单数据,并包装 ServletRequest 通过 ServletRequest.getParameter() 系列方法使表单数据可用。

转发过滤器

当请求通过代理(如负载均衡器)时,主机、端口和方案可能会发生变化,这使得从客户端角度创建指向正确主机、端口和方案的链接成为一项挑战。

RFC 7239 定义了 Forwarded HTTP 头,代理可以使用它来提供有关原始请求的信息。还有其他非标准头,包括 X-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-SslX-Forwarded-Prefix

ForwardedHeaderFilter 是一个 Servlet 过滤器,它修改请求以便 a) 根据 Forwarded 头更改主机、端口和 schemeb) 删除这些头以消除进一步的影响。该过滤器依赖于包装请求,因此它必须排在其他过滤器之前,例如 RequestContextFilter,它应该与修改后的请求一起使用,而不是原始请求。

Forwarded 头有安全考量,因为应用程序无法知道头是由代理按预期添加的,还是由恶意客户端添加的。这就是为什么应将信任边界处的代理配置为删除来自外部的不受信任的 Forwarded 头。还可以使用 removeOnly=true 配置 ForwardedHeaderFilter,在这种情况下它会删除但不使用头。

为了支持异步请求和错误分派,此过滤器应使用 DispatcherType.ASYNCDispatcherType.ERROR 进行映射。如果使用 Spring Framework 的 AbstractAnnotationConfigDispatcherServletInitializer(参见 Servlet Config),所有过滤器都会自动为所有调度类型注册。但是,如果通过 web.xml 或在 Spring Boot 中通过 FilterRegistrationBean 注册过滤器,请确保除了 DispatcherType.REQUEST 之外还包括 DispatcherType.ASYNCDispatcherType.ERROR

ETag 过滤器

ShallowEtagHeaderFilter 过滤器通过缓存写入响应的内容并从中计算 MD5 哈希来创建“浅”ETag。下次客户端发送时它会做同样的事情但它还会将计算值与 If-None-Match 请求标头进行比较,如果两者相等,则返回 304 (NOT_MODIFIED)。

此策略节省网络带宽但不节省 CPU因为必须为每个请求计算完整响应。前面描述的控制器级别的其他策略可以避免计算。

此过滤器有一个 writeWeakETag 参数,该参数将过滤器配置为写入类似于以下内容的弱 ETagW"02a2d595e6ed9a0b24f027f2b63b134d6"(如 RFC 7232 Section 2.3 中所定义)。

为了支持异步请求,这个过滤器必须用 DispatcherType.ASYNC 映射,这样过滤器才能延迟并成功生成一个 ETag 到最后最后一次异步调度。如果使用 Spring Framework 的 AbstractAnnotationConfigDispatcherServletInitializer,所有过滤器都会自动为所有调度类型注册。但是,如果通过 web.xml 或在 Spring Boot 中通过 FilterRegistrationBean 注册过滤器,请确保包含 DispatcherType.ASYNC

跨域过滤器

Spring MVC 通过控制器上的注解为 CORS 配置提供细粒度支持。但是,当与 Spring Security 一起使用时,建议依赖内置的 CorsFilter,它必须在 Spring Security 的过滤器链之前订阅。

参考资料