将 POST 的有效负载记录到雄猫

2022-09-02 04:29:49

我设法通过编辑conf/server.xml并取消注释org.apache.catalina.valves.AccessLogValve Valve的条目,在Tomcat中启用访问日志记录。我希望能够转储POST有效负载的内容。模式中似乎没有任何选项可以做到这一点。有没有内置的方法可以做到这一点?我是否使用 AccessLogValve?


答案 1

由于没有建议使用内置方式来获取 POST 有效负载,因此我继续编写了一个转储有效负载内容的自定义筛选器。具体说来:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                     FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    LOG.debug("payload: " + requestWrapper.getRequestBody());

和:web.xml

<filter>
    <filter-name>PayloadLoggingFilter</filter-name>
    <filter-class>com.host.PayloadLoggingFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>PayloadLoggingFilter</filter-name>
    <url-pattern>/resources/*</url-pattern>
</filter-mapping>

答案 2
  1. 在网络应用网站中.xml添加:

    <filter>
      <filter-name>PayloadLoggingFilter</filter-name>
      <filter-class>your.MyLogFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>PayloadLoggingFilter</filter-name>
      <url-pattern>/path/*</url-pattern>
    </filter-mapping>
    
  2. 创建过滤器:

    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Locale;
    import java.util.Map;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletInputStream;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.io.output.TeeOutputStream;
    
    import com.liferay.portal.kernel.log.Log;
    import com.liferay.portal.kernel.log.LogFactoryUtil;
    import com.liferay.util.servlet.ServletInputStreamWrapper;
    
    public class MyLogFilter implements Filter {
    
        private static final Log logger = LogFactoryUtil.getLog(MyLogFilter.class);
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            try {
                HttpServletRequest httpServletRequest = (HttpServletRequest) request;
                HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    
                Map<String, String> requestMap = this.getTypesafeRequestMap(httpServletRequest);
                BufferedRequestWrapper bufferedReqest = new BufferedRequestWrapper(httpServletRequest);
                BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(httpServletResponse);
    
                chain.doFilter(bufferedReqest, bufferedResponse);
    
                if(bufferedResponse.getContent()!=null){    //Response
                    final StringBuilder resMessage = new StringBuilder();
                    resMessage.append(" [RESPONSE:")
                            .append(bufferedResponse.getContent() )
                            .append("]");
                    logger.info(resMessage);
                }
                else{ //Request
                    final StringBuilder reqMessage = new StringBuilder(
                            "REST Request - ").append("[HTTP METHOD:")
                            .append(httpServletRequest.getMethod())
                            .append("] [PATH INFO:")
                            .append(httpServletRequest.getPathInfo())
                            .append("] [REQUEST PARAMETERS:").append(requestMap)
                            .append("] [REQUEST BODY:")
                            .append(bufferedReqest.getRequestBody())
                            .append("] [REMOTE ADDRESS:")
                            .append(httpServletRequest.getRemoteAddr()).append("]");
                    logger.info(reqMessage);
                }
    
    
            } catch (Throwable a) {
                logger.error(a);
            }
        }
    
        private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
            Map<String, String> typesafeRequestMap = new HashMap<String, String>();
            Enumeration<?> requestParamNames = request.getParameterNames();
            while (requestParamNames.hasMoreElements()) {
                String requestParamName = (String) requestParamNames.nextElement();
                String requestParamValue = request.getParameter(requestParamName);
                typesafeRequestMap.put(requestParamName, requestParamValue);
            }
            return typesafeRequestMap;
        }
    
        @Override
        public void destroy() {
        }
    
        private static final class BufferedRequestWrapper extends
                HttpServletRequestWrapper {
    
            private ByteArrayInputStream bais = null;
            private ByteArrayOutputStream baos = null;
            private BufferedServletInputStream bsis = null;
            private byte[] buffer = null;
    
            public BufferedRequestWrapper(HttpServletRequest req)
                    throws IOException {
                super(req);
                // Read InputStream and store its content in a buffer.
                InputStream is = req.getInputStream();
                this.baos = new ByteArrayOutputStream();
                byte buf[] = new byte[1024];
                int letti;
                while ((letti = is.read(buf)) > 0) {
                    this.baos.write(buf, 0, letti);
                }
                this.buffer = this.baos.toByteArray();
            }
    
            @Override
            public ServletInputStream getInputStream() {
                this.bais = new ByteArrayInputStream(this.buffer);
                this.bsis = new BufferedServletInputStream(this.bais);
    
                return this.bsis;
            }
    
            @Override
            public BufferedReader getReader() throws IOException {
                return new BufferedReader(new InputStreamReader(this.getInputStream()));
            }
    
            String getRequestBody() throws IOException {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        this.getInputStream()));
                String line = null;
                StringBuilder inputBuffer = new StringBuilder();
                do {
                    line = reader.readLine();
                    if (null != line) {
                        inputBuffer.append(line.trim());
                    }
                } while (line != null);
                reader.close();
                return inputBuffer.toString().trim();
            }
    
        }
    
        private static final class BufferedServletInputStream extends
                ServletInputStream {
    
            private ByteArrayInputStream bais;
    
            public BufferedServletInputStream(ByteArrayInputStream bais) {
                this.bais = bais;
            }
    
            @Override
            public int available() {
                return this.bais.available();
            }
    
            @Override
            public int read() {
                return this.bais.read();
            }
    
            @Override
            public int read(byte[] buf, int off, int len) {
                return this.bais.read(buf, off, len);
            }
    
        }
    
        public class TeeServletOutputStream extends ServletOutputStream {
    
            private final TeeOutputStream targetStream;
    
            public TeeServletOutputStream(OutputStream one, OutputStream two) {
                targetStream = new TeeOutputStream(one, two);
            }
    
            @Override
            public void write(int arg0) throws IOException {
                this.targetStream.write(arg0);
            }
    
            public void flush() throws IOException {
                super.flush();
                this.targetStream.flush();
            }
    
            public void close() throws IOException {
                super.close();
                this.targetStream.close();
            }
        }
    
        public class BufferedResponseWrapper implements HttpServletResponse {
    
            HttpServletResponse original;
            TeeServletOutputStream teeStream;
            PrintWriter teeWriter;
            ByteArrayOutputStream bos;
    
            public BufferedResponseWrapper(HttpServletResponse response) {
                original = response;
            }
    
            public String getContent() {
                if(bos == null){
                    return null;
                }
                return bos.toString();
            }
    
            @Override
            public PrintWriter getWriter() throws IOException {
    
                if (this.teeWriter == null) {
                    this.teeWriter = new PrintWriter(new OutputStreamWriter(
                            getOutputStream()));
                }
                return this.teeWriter;
            }
    
            @Override
            public ServletOutputStream getOutputStream() throws IOException {
    
                if (teeStream == null) {
                    bos = new ByteArrayOutputStream();
                    teeStream = new TeeServletOutputStream(
                            original.getOutputStream(), bos);
                }
                return teeStream;
            }
    
            @Override
            public String getCharacterEncoding() {
                return original.getCharacterEncoding();
            }
    
            @Override
            public String getContentType() {
                return original.getContentType();
            }
    
            @Override
            public void setCharacterEncoding(String charset) {
                original.setCharacterEncoding(charset);
            }
    
            @Override
            public void setContentLength(int len) {
                original.setContentLength(len);
            }
    
            @Override
            public void setContentType(String type) {
                original.setContentType(type);
            }
    
            @Override
            public void setBufferSize(int size) {
                original.setBufferSize(size);
            }
    
            @Override
            public int getBufferSize() {
                return original.getBufferSize();
            }
    
            @Override
            public void flushBuffer() throws IOException {
                if (teeStream != null) {
                    teeStream.flush();
                }
                if (this.teeWriter != null) {
                    this.teeWriter.flush();
                }
            }
    
            @Override
            public void resetBuffer() {
                original.resetBuffer();
            }
    
            @Override
            public boolean isCommitted() {
                return original.isCommitted();
            }
    
            @Override
            public void reset() {
                original.reset();
            }
    
            @Override
            public void setLocale(Locale loc) {
                original.setLocale(loc);
            }
    
            @Override
            public Locale getLocale() {
                return original.getLocale();
            }
    
            @Override
            public void addCookie(Cookie cookie) {
                original.addCookie(cookie);
            }
    
            @Override
            public boolean containsHeader(String name) {
                return original.containsHeader(name);
            }
    
            @Override
            public String encodeURL(String url) {
                return original.encodeURL(url);
            }
    
            @Override
            public String encodeRedirectURL(String url) {
                return original.encodeRedirectURL(url);
            }
    
            @SuppressWarnings("deprecation")
            @Override
            public String encodeUrl(String url) {
                return original.encodeUrl(url);
            }
    
            @SuppressWarnings("deprecation")
            @Override
            public String encodeRedirectUrl(String url) {
                return original.encodeRedirectUrl(url);
            }
    
            @Override
            public void sendError(int sc, String msg) throws IOException {
                original.sendError(sc, msg);
            }
    
            @Override
            public void sendError(int sc) throws IOException {
                original.sendError(sc);
            }
    
            @Override
            public void sendRedirect(String location) throws IOException {
                original.sendRedirect(location);
            }
    
            @Override
            public void setDateHeader(String name, long date) {
                original.setDateHeader(name, date);
            }
    
            @Override
            public void addDateHeader(String name, long date) {
                original.addDateHeader(name, date);
            }
    
            @Override
            public void setHeader(String name, String value) {
                original.setHeader(name, value);
            }
    
            @Override
            public void addHeader(String name, String value) {
                original.addHeader(name, value);
            }
    
            @Override
            public void setIntHeader(String name, int value) {
                original.setIntHeader(name, value);
            }
    
            @Override
            public void addIntHeader(String name, int value) {
                original.addIntHeader(name, value);
            }
    
            @Override
            public void setStatus(int sc) {
                original.setStatus(sc);
            }
    
            @SuppressWarnings("deprecation")
            @Override
            public void setStatus(int sc, String sm) {
                original.setStatus(sc, sm);
            }
    
        }
    
    }
    

推荐