[SPR-10683] ContentNegotiatingViewResolver does not select any views if no content types are requested Created: 24/Jun/13  Updated: 15/Jan/19  Resolved: 18/Jul/13

Status: Closed
Project: Spring Framework
Component/s: Web
Affects Version/s: 3.2.3
Fix Version/s: 3.2.4, 4.0 M2

Type: Bug Priority: Critical
Reporter: Jeff Knecht Assignee: Rossen Stoyanchev
Resolution: Complete Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive ie-refresh.zip    
Issue Links:
Relate
is related to SPR-10761 ContentNegotiatingViewResolver Resolved
Days since last comment: 43 weeks ago
Last commented by a User: true
Last updater: Spring Issuemaster

 Description   

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)


 Comments   
Comment by Phil Webb [ 24/Jun/13 ]

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

Comment by Jeff Knecht [ 24/Jun/13 ]

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
*/*
Comment by Phil Webb [ 24/Jun/13 ]

Thanks, that helps a lot.

Comment by Jeff Knecht [ 24/Jun/13 ]

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, */*
Comment by Jeff Knecht [ 24/Jun/13 ]

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;
}
Comment by Phil Webb [ 24/Jun/13 ]

Rossen Stoyanchev,

It looks like this commit may be the culprit.

Comment by Rossen Stoyanchev [ 18/Jul/13 ]

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.

Comment by Spring Issuemaster [ 14/Jan/19 ]

The Spring Framework has migrated to GitHub Issues. This issue corresponds to spring-projects/spring-framework#15311.

Generated at Tue Nov 12 00:35:21 UTC 2019 using Jira 7.13.8#713008-sha1:1606a5c1e7006e1ab135aac81f7a9566b2dbc3a6.