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

<mvc:view-resolvers> does not reliably find declared ContentNegotiationManager [SPR-13559] #18135

Closed
spring-projects-issues opened this issue Oct 9, 2015 · 3 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 9, 2015

Paul Chapman opened SPR-13559 and commented

In the following, does the ContentNegotiatingViewResolver created by <mvc:view-resolvers> automatically get set with the mvcContentNegotiationManager? My tests are telling me not.

	<mvc:annotation-driven
		content-negotiation-manager="mvcContentNegotiationManager" />

	<!-- View resolver chain -->
	<mvc:view-resolvers>
		<mvc:content-negotiation use-not-acceptable="true" />
		<mvc:bean-name />
		<mvc:tiles />
		<bean class="rewardsonline.accounts.JsonViewResolver" />
	</mvc:view-resolvers>

	<bean id="mvcContentNegotiationManager"
		class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
		<property name="ignoreAcceptHeader" value="true" />
		<property name="defaultContentType" value="text/html" />
	</bean>

Running this as a servlet app does work, but my MockMvc test fails trying to generate JSON.

If I explicitly get the ContentNegotiatingViewResolver when the test starts and manually set the ContentNegotiationManager to mvcContentNegotiationManager, it works.

I would expect the CNVR created using <mvc:view-resolvers/> to be initialised with the same ContentNegotiationManager that was specified to <mvc:annotation-driven>.


Affects: 4.1.7, 4.2.1

Referenced from: commits 0f1897d, c599514, 563a120, f84a0c9

Backported to: 4.1.9

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Oct 9, 2015

Rossen Stoyanchev commented

What version are you using? Also could you provide some details on how your tests indicate what CNVC is used?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Oct 11, 2015

Paul Chapman commented

I am using Spring V4.2.0.RELEASE.

The code I wrote did the following:

  1. Fetched the one and only view-resolver the application context. - turns out to be a ViewResolverComposite.
  2. Iterates over its view-resolvers to find the CNVR
  3. Found the one and only ContentNegotiationManager in the application context.
  4. Used reflection to access the contentNegotiationManager inside the CNVR
  5. Checked to see if the two ContentNegotiationManagers were the same instance - they weren't
  6. Used cnvr.setContentNegotiationManager(contentNegotiationManager) to set the ContentNegotiationManager in the CNVR instance to eb the one in the application context.

After that, when I ran my MockMvc test to fetch JSON, I did get JSON returned. Before it was returning HTML and my test failed - I think because the original ContentNegotiationManager in the CNVR instance was not the one I had configured to look for .json on the end of the URL.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Oct 19, 2015

Rossen Stoyanchev commented

It appears this is sensitive to where the "mvcContentNegotiationManager" bean appears. It works if it is before <mvc:view-resolvers>.

On the implementation side, ViewResolversBeanDefinitionParser is checking if context.getRegistry().containsBeanDefinition(beanName) where beanName is "mvcContentNegotiationManager". Two issues here, one it shouldn't be sensitive to the order of declaration and two it should work in cases where a ContentNegotiationManager is configured with a bean reference, i.e.:

<mvc:annotation-driven content-negotiation-manager="myManager" />
<bean id="myManager" class="..." />

@spring-projects-issues spring-projects-issues added type: bug A general bug status: backported An issue that has been backported to maintenance branches in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 4.2.3 milestone Jan 11, 2019
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) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants