Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
Fallback to defaultContentType if nothing more specific and producible has been specified in request [SPR-11114] #15740
I am developing a web service that supports 2 types of response: json and jsonp. For convenience I want that it responds in json by default.
Here is how I configured my contentNegotiationManager:
and my message converters:
What is interesting is what happen when no "format" parameter is defined in the request URL in addition to an Accept Header like this (generated by Firefox):
In this case ContentNegotiationManager.resolveMediaTypes() returns:
Note that the specified default content type "application/json" is not in the list.
Because "application/json" is missing on the list returned by resolveMediaTypes() when AbstractMessageConverterMethodProcessor.writeWithMessageConverters() is called it tries to match the requested media types to the producible ones. In my example:
I don't think it's a bug, defaultContentType is applied only if nothing but */* is defined in the request. Here there are specific content types (html and xml) in the request but none of them is supported, so the first declared producible type is returned.
It would be nice to have a mechanism to fallback to the defaultContentType if nothing more specific (and producible) has been set in the request.
For now I work around the issue by explicitly declaring the json converter before the jsonp one so that json is returned first in the list of producible types:
<mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json</value> </list> </property> </bean> <bean class="com.citygrid.sem.bid.api.jsonp.JsonpMessageConvertor"> <property name="supportedMediaTypes"> <list> <value>application/json</value> </list> </property> </bean> </mvc:message-converters>
One solution I can think of is to modify ContentNegotiationManager.resolveMediaTypes() to returned all content types matched by all strategies (sorted with MediaType.sortBySpecificityAndQuality()) but I understand that it could slow down AbstractMessageConverterMethodProcessor.writeWithMessageConverters()... what do you guys think? I can put together a pull request with this solution if you want.
Referenced from: commits 134ceac
Rossen Stoyanchev commented
I'm wondering why in the described scenario you don't turn off Accept header checking (i.e. ignoreAcceptHeader=true) and rely exclusively on a parameter or the default content type? You should then get the desired behavior, i.e. falling back on the default content type.
Armel Bourgon commented
Sorry long time without replying. I tested this with 3.2.4-RELEASE. But from what I see in github master branch nothing changed regarding this issue.
The idea was the following:
Now that I thought more about the issue I see that the solution I proposed wouldn't work because of 2.
Rossen Stoyanchev commented
It's been a while since this was created but we are making some changes and reviewing the options in this area.
The purpose of ContentNegotiationStrategy was and still is to provide flexibility and plugability that should help with these types of scenarios. For example it would be trivial to create a custom strategy that delegates to
So I'm scheduling for 5.0 RC2 to improve the configuration to make it easy to configure your own list of strategies ignoring the default setup.