-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
Take the following HttpMessageConverter setup in a Spring Boot application:
- An
HMCregistered to handle theapplication/hal+jsonmedia type (via Spring HATEOAS). - The default
MappingJackson2HttpMessageConverterregistered to handleapplication/jsonandapplication/*+json.
An HTTP request with Accept: application/prs.hal-forms+json, application/hal+json header will produce a response with Content-Type: application/prs.hal-forms+json which I think is wrong. The returned content type should be application/hal+json.
Here's what happens: AbstractMessageConverterMethodProcessor.writeWithMessageConverters(…) iterates over all acceptable types, starting with application/prs.hal-forms+json and checks it for compatibility with the producible media types. The HAL HMC does not match but the default Jackson one matches due to the support of application/*+json.
In the next step, getMostSpecificMediaType(…) is called and that match turns from a wildcard match into a concrete match. I.e. the match is treated as if application/prs.hal-forms+json had been matched explicitly. The now following concrete match for the HAL HMC and application/hal+json ends up second in the line in mediaTypesToUse.
That "upgrade" in the match causes the subsequent MediaType.sortBySpecificityAndQuality(mediaTypesToUse) to be without effect on the ordering as the first, actually wildcard match, is treated as concrete. As a consequence, the fallback HMC gets used instead of the actual concrete match of application/hal+json and is not even able to render the object according to the media type specification.
I've prepared a reproducing example here.