将 POST 的负载记录到 Tomcat

新手上路,请多包涵

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

原文由 Tim 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 475
2 个回答

由于没有关于获取 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>

原文由 Tim 发布,翻译遵循 CC BY-SA 4.0 许可协议

  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>

  1. 创建您的过滤器:
    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);
           }

       }

   }

原文由 Hao Deng 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题