0

当使用javax.servlet.servlet-api:2.53.0.1为Tomcat我遇到了一个问题,调整日志过滤器。日志消息的Tomcat的日志过滤器不编码响应体正常

部分被适当地编码UTF-8,而另一部分具有一定的编码的问题(未知编码)。

问题:bufferedResponse.getContent()返回奇怪编码的字符串

输出:

713901 [http-bio-8080-exec-7] ERROR com.example.filters.ReqRespDumpFilter - java.lang.NullPointerException 
713962 [http-bio-8080-exec-7] DEBUG com.example.filters.ReqRespDumpFilter - REST Request - [HTTP METHOD:GET] [PATH INFO:null] [REQUEST PARAMETERS:{}] [REQUEST BODY:] [REMOTE ADDRESS:0:0:0:0:0:0:0:1] [RESPONSE: (�h�h& �� 
    �v 
    �00h�"00�.)00��7(�����������������������������������������������������������x��x�x���w�w�w������x��w�xx��x��wx�������������x�����������������������������������������������(@���������������������������������������������������������������������������q��e��l��n��f��s��n��n��y��p��q��n��y��u��n����q��|��n��k��d��]��W��]��X��C��J��N��V��O��<��5��*��,����|}~uz}ft~\mwYYY "$���BBBBBBBBBBBBBBBBBBBBB-BB,/4BB(=A'2:1BB?7379;8.%BB(38820BB 
>65!$BB ,!#[email protected] 
!BB&,*&+BB= <BBBBBBBBBBBBBBBBBBBBB��������������������������������(@��������������������������������������������������������������������������������������������������������������������嘥�d��������i����������������������Ӑ��W��N��������������~��tz~ "$������n��D��,��X�����������������\mw8��J��?��*����7��]��y����������������������I��4��4��A��]��q��e����������������������ft~O��V��s��p��n��n�㓙���������������������ݹ��m��l��p��q��n�݉�����������������YYY���������d��n��k��f��y��������������������������u��j�����|��q��n��������������������������vy{������������|}~�����������������������������������������������������������������������������������������������������������������������(@����������������������������������������������������������������������������������������������������������������x��������������x������������w������p��x��w������x��wwx�����x�����wwx�������w�wwww��������w��wwx�������x���www��������������ww�����������������������w���x�����������w�����������w�x�x���x������wxw�w�����x��xxwww�����w�����w��������������wx�����������w�x�����������������������x�������������������������������������������������������������������(@�������������������������������������������������������������p��c��i��a��c��i��j��k��d��Z��]��U��T��^��k��q��r��p��q��r��m��n��n��n��q��q��o��n��m��n��l��{��~��j��j��k��e��h��e��Q��J��B��K��G��K��O��X��Z��S��0��:��;��3��6��7��+��'��"��.����s|�oy�gx�gw�S}�^z�]v�Rz�Uv�Ss�{||qy~sssku{mptgqwjnranxbmtiiiccc]t~[ozXksVlxRhtUdiMbnZ_dLZbYYYQY^PWYUUUHX_FSZMMMCCC>DF<<<59:048+./���||||||||||||||||||||||||||||||||||||||||| 


RBCp||l=D [email protected]@U 
||B=nn 
]AKJP||>ad|Zf>HHG]||b<t|q]X=KKNDo||V>Q 
u||cSX>HLEENAV|| D=mTWYk>=GNLKHHKGTm||mGMMGTLENHHHHK=g5b||^;LKGXGHHHHHK?e#6|| 
TDGIHHNHNLGh9|| 

xGG>L=F=<g'$('`||[email protected]*+e0)jn || 
    l|YOGg$/g0e2"_|| 
[CAV,,)17||Z:!1V/0e./||Zqn 
6-,/4|| 
    \||tZ.*/%)P||[*5(]||P28+&{5*02]||32|c 

Z|63||xwnz|| \Z 
|||||||||||||||||||||||||||||||||||||||||(@�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������gx�X��Y��PWYZ^cA��S�����������������������������������������������������������������cntJ��=��L��^z�������X��@��������������������������XXXXXX�����������������������뮮�iv}O��-��7��q|����������������K��anx���������������cccxxx��������������������Ո��[ozK��5��5��8��ju{������������������bovK��������������NNNSSS��������������۠��ksxUw�C��*��+��.��S��QY^������������������������Zv�J��oy����CCCjjj���������gw�Vv�K��5��'��0��0��,��O��_t�������������������������������T��G��K[eT�Rz�Ss�MbnK��B��8��.��'��-��1��3��-��9��Q|�OZ`������������������������������������IZa=��"��"��9��S{�'��0��-��4��3��3��3��*��C��Siui��`kq������������������������������������mptQ��'��+��8��Tv�;��4��3��3��3��3��*��G��[sq��X��b��m�������������������������������؟��������S~�R��;��7��0��3��.��3��.��'��<��Vlxp��X��a��]��_��h�����������������������������������������69:>��<��J��'��@��:��B��H��Qhts��Z��p��l��p��c��j��jnr���������������������������������������w}�048L��S��HX_4��O��FSZ>DFm��X��n��]s}m��_��l��Udi[[[�����������������㓓����������������������Z_dSr���9��Rhtt��`��m��Xksl��^t~k��c��k��gqw�����������������ꌌ����������������������������px}Z��N��]u�c��]��q��q��h��o��n��a��^��k��������������������������������������������������������zzze��^��l��n��_w�l��m��^t~o��b��n����������������������҉��������������VVVXXX������������h��f��d��h��q��k��a��q��o��f��m��~��������������������������������tttKKK���������y|~e��`��o��o��o��h��b��c��p��n��c��s{���������������������������������ٚ�����������������rze��X��d��n��i��j��n��X��U��T��d��jtz���������������������������������������������������q{�f��l��e��m��q��l��l��n��l��g��mw}���������������������������������������������������{��l��hhh��ó�����������{{{h��{��������������������������������������������������������49:<<<���������������������ZZZ+./���������������������������������������������������������qqq������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(0`��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ww�����������������x�������������������x�wx��x�����������������w����x�������������w�w��px�������������ww���������pw����x��w�x��������������ww��������������www�x�����������wwwwx��������w���wwwwwwx�����������ww�wwwwwwx�����������www�wwwwww�������������ww�wwwwwx�p�����������wwwww��ww�����������wwwwww���x��������x�x�����xx�����������������x�x�������������������x�������������wx�p�����������������x�wxw��x���������������wx�w�w���������������p������������p��x�p����xw������������x�����������x�������x��ww�x��������x�������ww�w�x������������������wx��������������p��x����������������www�x�������������x�������������������p������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(0`� 
���������������������������������������������������d��k��a��e��j��k��l��e��\��[��R��l��q��p��p��q��q��p��n��o��o��o��o��A��p��q��n��o��n��n��n��l��n��j��i��g��g��f��e��Q��I��K��D��J��M��Q��0��;��3��3��6��+��'��"��.��*��%��!����?��d~�a{�R|�_w�Sy�Sv�Sq�{{{tttat}kkkccc]r|[oyQl|WiqPfs_abUemUaeOfrNcn]^aQ]dL^hLZcHWaGX`GWa]^^TXZUUUHX_KU[LQTGT\IOTCMRKKKDJLAFJFFF>EK<CF9=A7>B<<<38:47:012.23./0*,.'))&')" 
(the output is too long) 
] 

新添加在servlet-api:3.0.1HttpServletResponse方法:

​​

滤波器代码:

package com.example.filters; 

import java.io.*; 
import java.util.*; 

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 org.apache.log4j.Logger; 

public class ReqRespDumpFilter implements Filter { 


    private static final Logger logger = Logger.getLogger(ReqRespDumpFilter.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); 

      final StringBuilder logMessage = 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("]"); 

      chain.doFilter(bufferedReqest, bufferedResponse); 
      logMessage.append(" [RESPONSE:").append(bufferedResponse.getContent()).append("]"); 
      logger.debug(logMessage); 
     } 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; 
     } 


     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 tee; 
     ByteArrayOutputStream bos; 

     public BufferedResponseWrapper(HttpServletResponse response) { 
      original = response; 
     } 

     public String getContent() { return bos.toString(); } 

     public PrintWriter getWriter() throws IOException { 
      return original.getWriter(); 
     } 

     public ServletOutputStream getOutputStream() throws IOException { 
      if (tee == null) { 
       bos = new ByteArrayOutputStream(); 
       tee = new TeeServletOutputStream(original.getOutputStream(), bos); 
      } 
      return tee; 

     } 

     @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 { 
      tee.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); 
     } 

     @Override 
     public int getStatus() { 
      return 0; 
     } 

     @Override 
     public String getHeader(String s) { 
      return "unsupported"; 
     } 

     @Override 
     public Collection<String> getHeaders(String s) { 
      return Collections.emptyList(); 
     } 

     @Override 
     public Collection<String> getHeaderNames() { 
      return Collections.emptyList(); 
     } 

    } 

} 

回答

0

寻找更深的请求的URL(httpServletRequest.getRequestURL())后,我发现,过滤器正常工作。

  • java.lang.NullPointerException意味着没有返回本体(例如高速缓存的网站返回304个状态和没有体)
  • 的 奇怪编码的字符串属于图像
  • 对于文本和HTML数据的 正确编码串是返回(网站被chached和困惑我,因为没有HTML代码正在记录)