Spring: Returning empty HTTP Responses with ResponseEntity<Void> doesn't work
NOTE: This is true for the version mentioned in the question, 4.1.1.RELEASE.
Spring MVC handles a ResponseEntity
return value through HttpEntityMethodProcessor
.
When the ResponseEntity
value doesn't have a body set, as is the case in your snippet, HttpEntityMethodProcessor
tries to determine a content type for the response body from the parameterization of the ResponseEntity
return type in the signature of the @RequestMapping
handler method.
So for
public ResponseEntity<Void> taxonomyPackageExists( @PathVariable final String key ) {
that type will be Void
. HttpEntityMethodProcessor
will then loop through all its registered HttpMessageConverter
instances and find one that can write a body for a Void
type. Depending on your configuration, it may or may not find any.
If it does find any, it still needs to make sure that the corresponding body will be written with a Content-Type that matches the type(s) provided in the request's Accept
header, application/xml
in your case.
If after all these checks, no such HttpMessageConverter
exists, Spring MVC will decide that it cannot produce an acceptable response and therefore return a 406 Not Acceptable HTTP response.
With ResponseEntity<String>
, Spring will use String
as the response body and find StringHttpMessageConverter
as a handler. And since StringHttpMessageHandler
can produce content for any media type (provided in the Accept
header), it will be able to handle the application/xml
that your client is requesting.
Spring MVC has since been changed to only return 406 if the body in the ResponseEntity
is NOT null
. You won't see the behavior in the original question if you're using a more recent version of Spring MVC.
In iddy85's solution, which seems to suggest ResponseEntity<?>
, the type for the body will be inferred as Object
. If you have the correct libraries in your classpath, ie. Jackson (version > 2.5.0) and its XML extension, Spring MVC will have access to MappingJackson2XmlHttpMessageConverter
which it can use to produce application/xml
for the type Object
. Their solution only works under these conditions. Otherwise, it will fail for the same reason I've described above.
According Spring 4 MVC ResponseEntity.BodyBuilder and ResponseEntity Enhancements Example it could be written as:
....
return ResponseEntity.ok().build();
....
return ResponseEntity.noContent().build();
UPDATE:
If returned value is Optional
there are convinient method, returned ok()
or notFound()
:
return ResponseEntity.of(optional)
You can also not specify the type parameter which seems a bit cleaner and what Spring intended when looking at the docs:
@RequestMapping(method = RequestMethod.HEAD, value = Constants.KEY )
public ResponseEntity taxonomyPackageExists( @PathVariable final String key ){
// ...
return new ResponseEntity(HttpStatus.NO_CONTENT);
}