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 select any views if no content types are requested [SPR-10683] #15311

Closed
spring-issuemaster opened this issue Jun 24, 2013 · 7 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Jun 24, 2013

Jeff Knecht opened SPR-10683 and commented

Browser: Internet Explorer 8
App Server: Tomcat 6.0.36
JVM version: 1.7

A spring web-mvc project fails with the following ViewResolver error when the user clicks the refresh button or 'F5' in Internet Explorer 8. This behavior functions correctly in Spring 3.2.2 and appears to have broken in Spring 3.2.3.

A small web project demonstrating the issue is attached.

SEVERE: Servlet.service() for servlet appServlet threw exception
javax.servlet.ServletException: Could not resolve view with name 'index' in servlet with name 'appServlet'
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1190)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:722)

Affects: 3.2.3

Attachments:

Issue Links:

  • #15387 ContentNegotiatingViewResolver

Referenced from: commits 675ec4c, 7fdd0c2

0 votes, 6 watchers

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 24, 2013

Phil Webb commented

Unfortunately I do not have access to IE 8, however, I have been unable to reproduce this error in IE 9, Firefox or Chrome with the sample project that you provided.

Does your sample application work correctly with other browsers? You say that the refresh button fails, does this mean that the initial request works? Have you got any unusual extensions or plug-ins installed to IE?

If possible could you debug your application and step into the DispatcherServlet.resolveViewName method. It would be useful to know the value of viewName. Could you also check if ContentNegotiatingViewResolver is called and if so what the requestedMediaTypes are (line 279).

Cheers

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 24, 2013

Jeff Knecht commented

ContentNegotiatingViewResolver is being called; but when fired via browser refresh, the requestedMediaTypes list is empty.

The list from other browsers:

Firefox:

text/html
application/xhtml+xml
application/xml;q=0.9
*/*;q=0.8

Chrome:

text/html
application/xhtml+xml
application/xml;q=0.9
*/*;q=0.8

IE9:

text/html
application/xhtml+xml
*/*
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 24, 2013

Phil Webb commented

Thanks, that helps a lot.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 24, 2013

Jeff Knecht commented

You've probably worked this out by now, but a bit more digging shows that the IE8 refresh is resulting in an empty list of acceptable media types from the content negotiation manager. This, of course, results in an empty list of compatible media types leading to the failed view resolution.

Note that IE8 IS sending the following header when refresh occurs:

accept : */*

This is different from what is sent when navigating via the address bar:

accept : application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 24, 2013

Jeff Knecht commented

The problem appears to be that when the only value in media types is */*, the method resolveMediaTypes in ConentNegotiationManager is returning Collections.emptyList() because it skips the return and continues on to the next strategy. If there are no more strategies to evaluate, then the loop exits without returning the mediatypes that it knows about. Line 124 seems to be the culprit.

Seems like this would be better:

public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {
    List<MediaType> resolvedMediaTypes = new ArrayList<MediaType>();
    for (ContentNegotiationStrategy strategy : this.contentNegotiationStrategies) {
        List<MediaType> mediaTypes = strategy.resolveMediaTypes(webRequest);
        for (MediaType mediaType : mediaTypes) {
            if (!resolvedMediaTypes.contains(mediaType)) {
                resolvedMediaTypes.add(mediaType);
            }
        }
    }
    return resolvedMediaTypes;
}
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 24, 2013

Phil Webb commented

Rossen Stoyanchev,

It looks like this commit may be the culprit.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jul 18, 2013

Rossen Stoyanchev commented

The referenced commit indeed exposed an issue in ContentNegotiatingViewResolver. The case of "*/*" and no requested media types should really mean the same thing .. that is the client accepts any media type. I've added a fix in CNVR to that extent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.