Java 将 POST 的有效负载记录到 Tomcat

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1528628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:52:28  来源:igfitidea点击:

Logging Payload of POSTs to Tomcat

javatomcat

提问by Tim

I've managed to enable access logging in Tomcat by editing the conf/server.xml and uncommenting the entry for the org.apache.catalina.valves.AccessLogValve Valve. I'd like to be able to dump the contents of POST's payload. It doesn't seem like any of the options in the pattern will do this. Is there a built in way to do this? Do I use the AccessLogValve?

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

采纳答案by Tim

Since there was not a suggestion of a built in way to get the POST payload, I went ahead and wrote a custom filter that dumps the contents of the payload. Specifically:

由于没有关于获取 POST 有效负载的内置方法的建议,我继续编写了一个自定义过滤器来转储有效负载的内容。具体来说:

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

and web.xml:

和 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>

回答by ZZ Coder

If the post is a form (application/x-www-urlencoded), you can use ExtendedAccessLogValve,

如果帖子是表单(application/x-www-urlencoded),可以使用ExtendedAccessLogValve,

http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/valves/ExtendedAccessLogValve.html

http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/valves/ExtendedAccessLogValve.html

You have to select individual parameters in the pattern like this,

您必须像这样在模式中选择单个参数,

  x-P(param_name)

回答by Janning

See RequestDumperValve or RequestDumperFilter here: http://tomcat.apache.org/tomcat-5.5-doc/config/valve.html#Request_Dumper_Valveit does what you want.

请参阅此处的 RequestDumperValve 或 RequestDumperFilter:http: //tomcat.apache.org/tomcat-5.5-doc/config/valve.html#Request_Dumper_Valve它可以满足 您的需求。

回答by Hao Deng

  1. In your webapp web.xml add:

    <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. Create your Filter:

    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);
            }
    
        }
    
    }
    
  1. 在您的 webapp web.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);
            }
    
        }
    
    }