Spring Boot 2.0.0中仅在响应阶段执行GenericFilterBean的实现问询
当然可以实现!其实Spring的Servlet Filter机制本身就支持这种「仅在响应阶段执行逻辑」的需求,和Jersey的ContainerResponseFilter异曲同工,咱们一步步来拆解:
核心原理:Servlet Filter的执行流程
Servlet Filter的doFilter方法天然包含两个关键阶段:
- 请求前置处理:在调用
filterChain.doFilter(request, response)之前的代码,会在请求到达控制器/业务逻辑前执行(对应Jersey的ContainerRequestFilter) - 响应后置处理:在
filterChain.doFilter(request, response)之后的代码,会在控制器处理完成、准备发送响应给客户端前执行——这正是你要的ContainerResponseFilter的效果!
具体实现步骤
1. 自定义响应过滤器(继承GenericFilterBean)
创建一个继承GenericFilterBean的过滤器,把响应逻辑放在filterChain.doFilter之后,甚至可以用try-finally确保即使请求处理抛出异常,响应逻辑也能执行(和Jersey的ContainerResponseFilter的异常处理行为完全一致):
import org.springframework.web.filter.GenericFilterBean; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ResponseOnlyFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { // 先让请求走完全部业务流程(控制器、服务层等) chain.doFilter(request, response); } finally { // 这里就是响应阶段的逻辑,无论请求成功/失败都会执行 HttpServletResponse httpResponse = (HttpServletResponse) response; // 示例:给响应头添加自定义标识 httpResponse.addHeader("X-Response-Filter", "Processed"); // 你可以在这里做任何响应相关操作:修改响应体、处理状态码、记录响应日志等 } } }
2. 注册过滤器
你可以通过Spring的@Bean方式注册这个过滤器,还能指定执行顺序(如果有多个过滤器的话):
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; @Configuration public class FilterConfig { @Bean @Order(Ordered.LOWEST_PRECEDENCE) // 确保这个过滤器最后执行,不影响其他前置过滤器 public ResponseOnlyFilter responseOnlyFilter() { return new ResponseOnlyFilter(); } }
如果是Spring Boot项目,也可以用@WebFilter注解标记过滤器类,然后在启动类上添加@ServletComponentScan来自动扫描注册:
import javax.servlet.annotation.WebFilter; @WebFilter(urlPatterns = "/*") // 指定要拦截的URL路径 public class ResponseOnlyFilter extends GenericFilterBean { // ... 实现代码同上 }
关键注意事项
- 异常处理:用
try-finally包裹chain.doFilter是核心,这样即使业务逻辑抛出异常,你的响应处理逻辑依然会执行,和Jersey的ContainerResponseFilter的行为对齐。 - 执行顺序:响应型过滤器一般设置为最低优先级(
Ordered.LOWEST_PRECEDENCE),确保它在所有前置过滤器之后执行,在响应发送前完成处理。 - 响应修改限制:如果响应已经被提交(比如控制器已经写出部分响应体),此时修改响应头或响应体可能抛出异常,建议使用
ContentCachingResponseWrapper缓存响应内容,方便后续修改。
这样实现的过滤器,就完全能达到你想要的「仅在服务返回响应时调用」的效果,和Jersey的ContainerResponseFilter功能完全匹配。
内容的提问来源于stack exchange,提问作者pijushcse
相关产品推荐
相关产品推荐

