前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring cached 的 wrapper 类读取请求响应内容

Spring cached 的 wrapper 类读取请求响应内容

作者头像
BUG弄潮儿
发布2021-05-17 15:36:28
3.2K0
发布2021-05-17 15:36:28
举报
文章被收录于专栏:JAVA乐园

0x01:wrapper 类说明

Servlet 的 request body 以及 response body 一旦流被读取了,就无法再次被读取了,因此这对于有些要做拦截业务请求来说,比较麻烦。那么如何处理这个业务场景呢?利用 filter,然后重写 HttpServletRequest 和 HttpServletResponse 包装一层,然后 proceed,最后 response 完之后在把cached 的 body 设置回原始响应。

Spring提供了 ContentCachingRequestWrapper 以及 ContentCachingResponseWrapper 两个类,来解决这类问题。

代码语言:javascript
复制
ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);

读取完 Response body 之后

代码语言:javascript
复制
wrappedResponse.copyBodyToResponse();

通过这个设置回去,就可以使得接口调用者可以正常接收响应了。

0x02:日志拦截实例

  • 继承OncePerRequestFilter,顾名思义该filter能够确保在一次请求只通过一次该 filter
  • 实现 Ordered,设置filter的执行顺序,一般设置最低级别执行
代码语言:javascript
复制
package com.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.Ordered;
import org.springframework.web.filter.OncePerRequestFilter;

public class LogFilter extends OncePerRequestFilter implements Ordered {

    @Override
    public int getOrder() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // TODO Auto-generated method stub

    }

}

完整代码大致如下

代码语言:javascript
复制
package com.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import org.springframework.web.util.WebUtils;

@Component
public class LogFilter extends OncePerRequestFilter implements Ordered {

    @Value("${openLog}")
    private boolean openLog;
    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE-8;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = null;
        ContentCachingResponseWrapper wrappedResponse = null;
        try{
            if(openLog){
                printHender(request);
                printCookie(request);
                printParameter(request);
                wrappedRequest = new ContentCachingRequestWrapper(request);
                wrappedResponse = new ContentCachingResponseWrapper(response);
                printRequest(wrappedRequest);
                printResponse(wrappedResponse);
            }else{
                filterChain.doFilter(request, response);
            }
        }finally {
            if(wrappedResponse!=null){
                wrappedResponse.copyBodyToResponse();
            }
        }

    }

    /**
     * 打印返回体
     * 
     * @param wrappedRequest
     */
    private void printResponse(ContentCachingResponseWrapper wrappedResponse) {
        try{
            ContentCachingResponseWrapper resp =  WebUtils.getNativeResponse(wrappedResponse, ContentCachingResponseWrapper.class);
            byte[] responseBody = resp.getContentAsByteArray();
            String body = new String(responseBody, resp.getCharacterEncoding());
            //TODO 打印

        }catch (Exception e) {
            // TODO: handle exception
        }

    }

    /**
     * 打印请求体
     * 
     * @param wrappedRequest
     */
    private void printRequest(ContentCachingRequestWrapper wrappedRequest) {
        try{
            ContentCachingRequestWrapper req =  WebUtils.getNativeRequest(wrappedRequest, ContentCachingRequestWrapper.class);
            byte[] reqestBody = req.getContentAsByteArray();
            String body = new String(reqestBody, req.getCharacterEncoding());
            //TODO 打印

        }catch (Exception e) {
            // TODO: handle exception
        }
    }

    /**
     * 打印参数
     * 
     * @param request
     */
    private void printParameter(HttpServletRequest request) {
        // TODO Auto-generated method stub

    }

    /**
     * 打印cookie
     * 
     * @param request
     */
    private void printCookie(HttpServletRequest request) {
        // TODO Auto-generated method stub

    }

    /**
     * 打印请求头
     * 
     * @param request
     */
    private void printHender(HttpServletRequest request) {
        // TODO Auto-generated method stub
        
    }

}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BUG弄潮儿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档