javaspringgoogle-app-enginespring-mvchttp-head

Spring MVC, Google App Engine, and filtering for HEAD requests


I have a simple Spring MVC 3.2 based application hosted on Google App Engine. Controllers return ModelAndView objects for GET requests, and the pages use JSP.

Instead of instrumenting each Controller with a handler for HEAD requests, I followed the instructions on this blog and created a filter: http://axelfontaine.com/blog/http-head.html

It works, except that the content length is never set and is returned as 0. Using breakpoints, I confirmed that the write methods in the NoBodyOutputStream class are not called, and when examining the source code of the ServletOutputStream and its base classes, I did not find other write methods that would be called instead (this could be an oversight on my part, though).

Has anyone had success in using a filter to handle HEAD requests in more recent versions of Spring MVC?

EDIT

GAE uses an embedded Jetty-6-1-x server.

Here is a sample controller:

@Controller
@RequestMapping("resources")
public class ResourcesController {

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView getResourcesPage() {
        return new ModelAndView("resources");
    }
}

Here is the relevant content from the web.xml file:

<filter>
    <filter-name>HttpHeadFilter</filter-name>
    <filter-class>com.foo.filter.HttpHeadFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>HttpHeadFilter</filter-name>
    <servlet-name>mvc-dispatcher</servlet-name>
</filter-mapping>

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

I modified the HttpHeadFilter, and the problem seems to be with how the request is wrapped, because the Controller's GET method is invoked but no response is written:

if (isHttpHead(httpServletRequest)) {
    chain.doFilter(new ForceGetRequestWrapper(httpServletRequest), response);
} else {
    chain.doFilter(request, response);    
}

Solution

  • This appears to be a known issue with Google App Engine: https://code.google.com/p/googleappengine/issues/detail?id=2719