欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java Web打印request body

程序员文章站 2022-07-12 11:46:58
...

默认的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体
        if (!Objects.equals(Req.ContentType.FORM_DATA, contentType)) {
            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;
    }
}