Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ContentNegotiatingViewResolver does not support wildcards in contentType [SPR-9807] #14440

Closed
spring-projects-issues opened this issue Sep 19, 2012 · 2 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Sep 19, 2012

Felix Barnsteiner opened SPR-9807 and commented

The following configuration won't work for accept headers containing e.g. application/vnd.foo.user+json (see also http://stackoverflow.com/questions/11880359/spring-mvc-3-1-1-contentnegotiatingviewresolver-how-to-use-wildcard-characters):

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1"/>
    <property name="favorPathExtension" value="false"/>
    <property name="defaultViews">
        <list>
            <!-- JSON View -->
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                <property name="contentType" value="application/*+json"/>
            </bean>                 
        </list>
    </property>
</bean>

The reason is a wrong comparison in ContentNegotiatingViewResolver#getBestView:

Current:

for (MediaType mediaType : requestedMediaTypes) {
    for (View candidateView : candidateViews) {
        if (StringUtils.hasText(candidateView.getContentType())) {
            MediaType candidateContentType = MediaType.parseMediaType(candidateView.getContentType());
            if (mediaType.includes(candidateContentType)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Returning [" + candidateView + "] based on requested media type '"
                            + mediaType + "'");
                }
                return candidateView;
            }
        }
    }
}

The problem is application/vnd.foo.user+json does not include application/*+json, the opposite is true.

Expected:

if (candidateContentType.includes(mediaType)) {

Affects: 3.1.2

Reference URL: http://stackoverflow.com/questions/11880359/spring-mvc-3-1-1-contentnegotiatingviewresolver-how-to-use-wildcard-characters

Issue Links:

Referenced from: commits c7e7e80

@spring-projects-issues
Copy link
Collaborator Author

Felix Barnsteiner commented

I've just realized, that there is a problem with that solution: If the client requests application/vnd.foo.user+json, it gets json, but the content-type header is set to application/*+json. So there is more to do:

response.setContentType(getContentType()); 

Is not valid then. The requested content type must be computed in the views and set:

response.setContentType(getRequestedContentType()); 

Generally, I feel the behaviour of @ResponseBody and ContentNegotiatingViewResolver is a bit inconsistent.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

This should now be supported as of commit c7e7e80a3ae9f6b4ed7f2d99fe321c2e12550d7b.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants