Java Web打印request body

默认的ServletInputStream不支持reset,所以默认的流只能读取一次,但是如果我们要打印body就需要读取inputStream,这会导致Spring无法读取body体,所以通过HttpServletRequestWrapper包装重新定义getInputStream(),让输入流从我们读出来的body体中读取数据。

@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {

    private final String body;
 
    RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        // 读取出来保存到body里
        try (InputStream in = new BufferedInputStream(request.getInputStream())) {
            this.body = StreamUtils.copyToString(in, Charset.defaultCharset());
        }
    }

    /**
     * 重写getInputStream方法,从body里读取
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) { }

            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }
 
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
 
    public String getBody() {
        return this.body;
    }
}

LogFilter

@Slf4j
public class LogFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        log.info("log filter init .......");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String requestURI = httpServletRequest.getRequestURI();
        // 包装request,可以打印多次body
        String body = "";
        // 去掉打印文件上传body
        String contentType = request.getContentType();
        // 如果是文件上传,不打印body体
        boolean notFileUpload = !StringUtils.startsWith(request.getContentType(), Req.ContentType.FORM_DATA);
        if (notFileUpload) {
            request = new RequestWrapper(httpServletRequest);
            body = ((RequestWrapper) request).getBody().replaceAll("[\r\n\t]", "").replaceAll("\"", "'");
        }
        Map<String, Object> params = getRequestParams(httpServletRequest);
        Map<String, Object> headers = getHeaders(httpServletRequest);
        LogRequest logRequest = LogRequest.builder()
                .body(body)
                .params(params)
                .headers(headers)
                .url(requestURI)
                .build();
        log.info("request = {}", JsonUtil.toJson(logRequest));
        filterChain.doFilter(request, servletResponse);
       
    }
    
    /**
     * 获取请求地址上的参数
     */
    private static Map<String, Object> getRequestParams(HttpServletRequest request) {
        Enumeration<String> enu = request.getParameterNames();
        Map<String, Object> params = Maps.newHashMap();
        //获取请求参数
        while (enu.hasMoreElements()) {
            String name = enu.nextElement();
            params.put(name, request.getParameter(name));
        }
        return params;
    }

    private static Map<String, Object> getHeaders(HttpServletRequest request) {
        Enumeration<String> enu = request.getHeaderNames();
        Map<String, Object> params = Maps.newHashMap();
        //获取请求参数
        while (enu.hasMoreElements()) {
            String name = enu.nextElement();
            params.put(name, request.getHeader(name));
        }
        return params;
    }
}
发布了44 篇原创文章 · 获赞 13 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_19457117/article/details/88633439