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