21
votes

recently we moved to spring 3.0 Controller handling like this:

@Controller
public class MyController {
   @RequestMapping(method = RequestMethod.POST)
   protected String onSubmit ( Form form, Errors errors) {
        // handle POST
   }

   @RequestMapping(method = RequestMethod.GET)
   protected void getForm ( Form form ) {
     // handle GET
   }
}

Now we are getting lots of Exceptions in our logs because of HEAD Requests.

org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'HEAD' not supported
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodResolver.resolveHandlerMethod(AnnotationMethodHandlerAdapter.java:621)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:422)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:415)
    ...

I would like to support HEAD Requests the same way like GET Requests, but obeying the HTTP reference of course:

The HEAD method is identical to GET except that the server MUST NOT
return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification. http://www.ietf.org/rfc/rfc2616.txt

Does anybody has an elegant solution or is there even a spring solution out-of-the-box?

I searched the web but did not find any answers to this.

3
What is making the HEAD requests? Could this be a mis-configuration on the client or client side code (Javascript)? I am asking because usually HEAD is meant to check for updates to the page (i.e. Cache-Control / LastModified headers) so the browser can update is necessary. - AngerClown
PycURL does a request method = head for doing gets. Usually, I have found that this is very normal for lot search engines like : oneriot.com, ask.com etc.. - Spring Monkey
who cares which tool is making HEAD Request. It is a valid HTTP Request and many browser are doing it actually (checking bookmarks or whatever). - Janning
According to below link spring should provide implicit HEAD and OPTIONS if they are not present for given request url, is it true from spring 4? or something else I am missing? spring docs mvc is the link. - Pavan Kumar

3 Answers

15
votes

Just add HEAD as a supported method the the request mapping:

@RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})

Update: I think you can provide a custom class that extends AnnotationMethodHandlerAdapter to be the method handler (in dispatcher-servlet.xml), and just bypass the HEAD support check there. But I'd just use the replace features of an IDE to add it.

15
votes

In the current Spring (4.3.10) HEAD is automatically supported:

@RequestMapping methods mapped to "GET" are also implicitly mapped to "HEAD", i.e. there is no need to have "HEAD" explicitly declared. An HTTP HEAD request is processed as if it were an HTTP GET except instead of writing the body only the number of bytes are counted and the "Content-Length" header set.

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestmapping-head-options