Spring 3.0 HEAD Requests

2019-04-03 18:29发布

问题:

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.

回答1:

I believe this is what you're looking for: http://www.axelfontaine.com/2009/09/transparently-supporting-http-head.html



回答2:

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.



回答3:

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