I want to add logging to my Servlet, so I've created Filter which should display request and go to the Servlet. But unfortunately I've encoutered exception:
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) So to fix this problem I've found solution with Wrapper, but it doesn't work. What else can I use/change in code? Any ideas?
[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); } }
Looks like the restlet framework has called getRequestEntityStream() on the Request object which in turn calls getInputStream(), so calling getReader() on the request throws IllegalStateException. The Servlet API documentation for getReader() and getInputStream() says:
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 From the documentation it seems that we cannot call both getReader() and getInputStream() on the Request object. I suggest you use getInputStream() rather than getReader() in your wrapper.
Use ContentCachingRequestWrapper class. Wrap HttpServletRequest in thi will resolve issue
Sample : if you want to convert your "HttpServletRequest servletRequest" you can do some thing like
import org.springframework.web.util.ContentCachingRequestWrapper; ContentCachingRequestWrapper request = new ContentCachingRequestWrapper(servletRequest); Hope it helps!!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With