如何查看来自过滤器的消息?

时间:2012-02-13 10:43:51

标签: java spring servlets servlet-filters

我尝试使用javax.servlet.Filter来查看邮件。

public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
     BufferedReader reader = request.getReader();
     if ( reader.markSupported() ) {
         reader.mark( contentLen );
     }
     String content = reader.readLine();

     // search some pattern

     if ( reader.markSupported() ) {
         reader.reset();
     }
     chain.doFilter( request, response );
}

最终收到请求的servlet会抛出此异常:

java.lang.IllegalStateException: getReader() has already been called for this request

根据javadoc,这是正确的行为。

我的问题是如何才能阅读输入流的内容?

我也试过ServletInputStream is = request.getInputStream();

3 个答案:

答案 0 :(得分:1)

未经测试,但您可能

  • 读取请求输入流中的所有字节并将其写入字节数组
  • 在此字节数组上构造一个缓冲读取器,以便在过滤器中读取您想要的内容,
  • 构造一个HttpServletRequestWrapper,它覆盖getInputStream()以返回字节数组上的流,
  • 将此包装器传递给过滤器链。

答案 1 :(得分:1)

按照@JB Nizet的方法导致了这段代码:

public class HttpServletRequestCopy extends HttpServletRequestWrapper {

    private final byte[]       buffer;

    private ServletInputStream sis;

    private BufferedReader     reader;

    public byte[] getBuffer() {
        return buffer;
    }

    public HttpServletRequestCopy( HttpServletRequest request) throws IOException {
        super( request );
        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        copyStream( request.getInputStream(), byteArrayOutputStream );
        buffer = byteArrayOutputStream.toByteArray();
    }

    @Override
    public BufferedReader getReader() throws IOException {
        if ( reader == null ) {
            String characterEncoding = this.getCharacterEncoding();
            if ( characterEncoding == null ) {
                reader = new BufferedReader( new InputStreamReader( this.getInputStream() ) );
            }
            else {
                reader = new BufferedReader( new InputStreamReader( this.getInputStream(), characterEncoding ) );
            }
        }
        return reader;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        if ( sis == null ) {
            final ByteArrayInputStream bais = new ByteArrayInputStream( buffer );
            sis = new ServletInputStream() {
                @Override
                public int read() throws IOException {
                    return bais.read();
                }
            };
        }
        return sis;
    }

    private void copyStream( InputStream input, OutputStream output) throws IOException {
        final byte[] bytes = new byte[ 1024 ];
        int length;
        while ( (length = input.read( bytes )) != -1 ) {
            output.write( bytes, 0, length );
        }
    }
}

答案 2 :(得分:0)

ServletRequest.getInputStream() ServletRequest.getReader()是 - 或者,如果已经调用了其中任何一个,则另一个将失败。您可以使用简单的try-catch来浏览:

try {
    request.getInputStream();
} catch (IllegalStateException e) {
    // someone already called getReader(), so use it instead
    request.getReader();
}

注意!未指定流或阅读器应该是可重置的,因此如果您使用任何字节,它们将不再可用于链中的任何过滤器或servlet。

相关问题