我想将日志记录添加到Servlet中,因此我创建了Filter,该过滤器应显示请求并转到Servlet。但不幸的是,我遇到了例外:
java.lang.IllegalStateException: getReader() has already been called for this request at org.apache.catalina.connector.Request.getInputStream(Request.java:948) at org.apache.catalina.connector.RequestFacade.getInputStream(RequestFacade.java:338) at com.noelios.restlet.ext.servlet.ServletCall.getRequestEntityStream(ServletCall.java:190)
因此,要解决此问题,我发现了Wrapper的解决方案,但它不起作用。我还能在代码中使用/更改什么?有任何想法吗?
[MyHttpServletRequestWrapper]
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); } private String getBodyAsString() { StringBuffer buff = new StringBuffer(); buff.append(" BODY_DATA START [ "); char[] charArr = new char[getContentLength()]; try { BufferedReader reader = new BufferedReader(getReader()); reader.read(charArr, 0, charArr.length); reader.close(); } catch (IOException e) { e.printStackTrace(); } buff.append(charArr); buff.append(" ] BODY_DATA END "); return buff.toString(); } public String toString() { return getBodyAsString(); } }
[MyFilter]
public class MyFilterimplements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { final HttpServletRequest httpServletRequest = (HttpServletRequest) request; final HttpServletResponse httpServletResponse = (HttpServletResponse) response; final HttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(httpServletRequest); final String requestBody = requestWrapper.toString(); chain.doFilter(request, response); } }
看起来restlet框架已经调用getRequestEntityStream()了Request对象,而该对象又被调用getInputStream(),因此getReader()对请求的调用将抛出IllegalStateException。用于getReader()和getInputStream()的Servlet API文档说:
getRequestEntityStream()
getInputStream()
getReader()
IllegalStateException
public java.io.BufferedReader getReader() ... ... Throws: java.lang.IllegalStateException - if getInputStream() method has been called on this request public ServletInputStream getInputStream() ... ... Throws: java.lang.IllegalStateException - if the getReader() method has already been called for this request
从文档看来,我们不能同时对Request对象调用getReader()和getInputStream()。我建议您使用getInputStream()而不是getReader()包装。