HttpServletRequestWrapper, Tomcat and forwards
I’ve been working on getting the JCatapult security framework to leverage Struts actions rather than a bunch of configuration and additional custom code. In order to pull all of this off, I had to modify the HttpServletRequest in order to make it seem like the requested URI was different than the original request URI. I used a HttpServletRequestWrapper in order to pull this off like this:
final HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(httpRequest) {
@Override
public String getRequestURI() {
return successfulLoginURI;
}
@Override
public String getServletPath() {
return successfulLoginURI;
}
@Override
public RequestDispatcher getRequestDispatcher(String uri) {
final RequestDispatcher rd = httpRequest.getRequestDispatcher(uri);
return new RequestDispatcher() {
public void forward(ServletRequest servletRequest, ServletResponse servletResponse)
throws ServletException, IOException {
rd.forward(httpRequest, servletResponse);
}
public void include(ServletRequest servletRequest, ServletResponse servletResponse)
throws ServletException, IOException {
rd.include(httpRequest, servletResponse);
}
};
}
};
As it turns out, I had to do that little tricky part at the end with the RequestDispatcher because Tomcat fails during a forward if the incoming HttpServletRequest is a wrapper.
February 19th, 2008 at 4:42 pm
How did you discover that tomcat failed on forwards when the request had been wrapped? I can’t find any information online and the workaround you are using will not work for me since I need to have the wrapped request for the resource being forwarded to.
February 21st, 2008 at 10:02 am
It was pretty simple. I just wrapped the request so that the request URI was something different. This was done in a filter. The request got passed down to struts and struts pulled out the new URI correctly and invoked the action. Once the action finished Struts tried to forward the request to the JSP and this is where it failed. The container was unable to perform the forward because the HttpServletRequest that was being passed to the request dispatcher had a different request URI and was a wrapper. Tomcat doesn’t like that and was throwing some strange exceptions back.