需求:记录每次用户请求Controller的Body参数,

思路:在每个Controller 该当中记录,容易漏记,如果在拦截器里面记的话,可以统一处理

问题:在postHandle 里面记,request.getInputStream() 取出来是空的,放在preHandle里面,就进不到 Controller 里面了。报:I/O error while reading input message; nested exception is java.io.IOException: Stream closed

原因:在拦截器已经读取了请求体中的内容,这时候请求的流中已经没有了数据,就是说HttpServletRequest请求体中的内容一旦读取就不不存在了,所以直接读取是不行的。

方案:对httprequest进行修饰,自定义的包装类来实现

添加 RequestLogFilter

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

 
@Component
@WebFilter(filterName = "requestLogFilter",urlPatterns = {"/*"}, initParams = {@WebInitParam(name = "ignoredUrl", value = ".css;.js;.jpg;.png;.gif;.ico;.html"), @WebInitParam(name = "filterPath", value = "/user/login#/user/registerUser")})

public class RequestLogFilter implements OncePerRequestFilter {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
 
    @Override
    protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
        RequestLogWrapper requestWapper = null;
        if (servletRequest instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            if(!request.getRequestURI().toLowerCase().contains("swagger")){
                requestWapper = new RequestLogWrapper(request);
            }
        }

        if (requestWapper != null) {
            filterChain.doFilter(requestWapper, servletResponse);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {
        logger.info(">>>> RequestLogFilter destroy <<<<");
    }
}

 

 

添加 RequestLogWapper

import cn.hutool.core.util.StrUtil; 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;


public class RequestLogWrapper extends HttpServletRequestWrapper {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private String requestBody;

    public String getRequestBody() {
        return requestBody;
    }

    public RequestLogWrapper(HttpServletRequest request) throws IOException {
        super(request);
        requestBody = getBodyString(request);
        String queryStr = StrUtil.isEmpty(request.getQueryString()) ? "" : "?" + request.getQueryString();
        logger.info("{}{}\r\n{}", request.getRequestURI(), queryStr, requestBody);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8));
        ServletInputStream servletInputStream = 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();
            }
        };
        return servletInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    public String getBodyString(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}

 

参考资源:

https://www.jianshu.com/p/ba2d5101ad90

https://blog.csdn.net/qq_38132283/article/details/107685797

相关文章:

  • 2022-12-23
  • 2021-11-12
  • 2022-01-12
  • 2021-09-19
  • 2021-05-01
  • 2021-08-12
  • 2021-08-07
猜你喜欢
  • 2022-03-10
  • 2022-12-23
  • 2022-12-23
  • 2021-08-19
  • 2021-12-19
  • 2021-07-29
相关资源
相似解决方案