专栏名称: Java编程精选
关注语言编程Java,分享、交流Java编程技巧和信息
目录
相关文章推荐
ImportNew  ·  1 个空指针,捅破谷歌云的天…… ·  昨天  
Java编程精选  ·  我司CTO:不要幻想着找技术强、能力全还吃苦 ... ·  2 天前  
程序员晓梦  ·  卧槽!又是一个Java神器! ·  昨天  
程序员晓梦  ·  卧槽!又是一个Java神器! ·  昨天  
51好读  ›  专栏  ›  Java编程精选

SpringBoot 内置的 10 个神器,让开发效率翻倍!

Java编程精选  · 公众号  · Java  · 2025-06-18 18:00

正文

请到「今天看啥」查看全文


完美解决了这一问题。

核心包装器

请求包装器( ContentCachingRequestWrapper ) : 缓存请求体字节数据,允许多次读取。典型场景:记录请求日志后,控制器仍能正常解析请求体。

响应包装器( ContentCachingResponseWrapper ) : 缓存响应输出流,支持在响应提交前修改内容(如添加签名、动态拼接数据)。

实战应用(过滤器实现)
// 请求包装器过滤器
@Componentpublicclass RequestLogFilter extends OncePerRequestFilter {    @Override    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)            throws ServletException, IOException {        // 包装请求,缓存输入流        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);        byte[] requestBody = wrappedRequest.getContentAsByteArray();                // 记录请求日志(可在此处添加自定义逻辑)        log.debug("Received request body: {}", new String(requestBody));                // 传递包装后的请求,确保后续组件能重复读取        filterChain.doFilter(wrappedRequest, response);    }}// 响应包装器过滤器@Componentpublicclass ResponseSignFilter extends OncePerRequestFilter {    @Override    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)            throws ServletException, IOException {        // 包装响应,缓存输出流        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);                // 执行后续处理(控制器逻辑)        filterChain.doFilter(request, wrappedResponse);                // 响应后处理:添加签名        byte[] responseBody = wrappedResponse.getContentAsByteArray();        String signature = generateSignature(responseBody);        wrappedResponse.setHeader("X-Response-Signature", signature);                // 必须调用此方法将缓存内容写入原始响应        wrappedResponse.copyBodyToResponse();    }    private String generateSignature(byte[] body) {        // 自定义签名逻辑        return Base64.getEncoder().encodeToString(body);    }}

三、单次执行保障:OncePerRequestFilter 基类

在请求转发( forward )或包含( include )场景中,普通过滤器可能重复执行,导致逻辑混乱。 OncePerRequestFilter 确保过滤器在请求生命周期内仅执行一次,是处理状态性逻辑的理想选择。

核心优势

避免重复处理: 通过 shouldNotFilter 方法内部逻辑,自动识别同一请求的多次调度,确保 doFilterInternal 仅执行一次。

简化开发: 只需重写 doFilterInternal 方法,无需手动处理请求标识或缓存执行状态。

适用场景

日志记录: 避免转发时重复打印日志。

安全校验:







请到「今天看啥」查看全文