Spring 3.2 content compliance class exception

We are developing a standard Java web application using Spring MVC and recently tried to upgrade from 3.0.6 to 3.2.0. Almost all responses to the servlet are JSP or Json representations, but there are some that are pdf requests with the extension β€œpdf”.

In Spring 3.0.6, we created this setting, taken from the Spring MVC documentation.

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="pdf" value="application/pdf"/> <entry key="html" value="text/html"/> <entry key="json" value="application/json"/> </map> 

which worked great in conjunction with XMLViewResolver.

After upgrading to 3.2.0, a crash occurred:

 Error creating bean with name' org.springframework.web.servlet.view.ContentNegotiatingViewResolver#0' defined in class path resource [dispatcher-test-servlet.xml]: Invocation of init method failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.http.MediaType' 

After examining the docs and some blogs, this configuration works:

 <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="contentNegotiationManager"> <bean class="org.springframework.web.accept.ContentNegotiationManager"> <constructor-arg> <list> <!-- These are evaluated in order --> <!-- Is there a media type based on suffix? --> <bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy"> <constructor-arg> <map> <entry key="html" value="text/html" /> <entry key="json" value="application/json" /> <entry key="pdf" value="application/pdf" /> </map> </constructor-arg> </bean> <!-- Else use request header --> <bean class="org.springframework.web.accept.HeaderContentNegotiationStrategy"> </bean> </list> </constructor-arg> </bean> </property> 

But we tried to launch the new MVC Spring test infrastructure using this configuration and get a ClassCast exception again, so it seems that the test environment does not initialize beans the same way as when the application starts ... Does anyone have a clear explanation on how to configure the ContentNegotiationViewResolver in Spring 3.2 in a reliable way? thanks

Richard

+4
source share
4 answers

With spring 3.2, it is better to enable with the ContentNegotiationManager . He works for me. You can use a static field, for example org.springframework.http.MediaType.APPLICATION_JSON_VALUE , to indicate a media type. check the following code:

 <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="contentNegotiationManager"> <bean class="org.springframework.web.accept.ContentNegotiationManager"> <constructor-arg> <bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy"> <constructor-arg> <map> <entry key="json"> <util:constant static-field="org.springframework.http.MediaType.APPLICATION_JSON_VALUE" /> </entry> <entry key="xml"> <util:constant static-field="org.springframework.http.MediaType.APPLICATION_XML_VALUE" /> </entry> </map> </constructor-arg> </bean> </constructor-arg> </bean> </property> <property name="defaultViews"> <list> <!-- default views --> </list> </property> </bean> 

To do this, you need to use the schema utility in your dispatcher-servlet.xml file, i.e. xmlns:util="http://www.springframework.org/schema/util" and layout location http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring -util-3.0.xsd

+7
source

I fixed the problem by removing duplicates of <mvc:annotation-driven/> from the xml configuration or @EnableWebMVC annotation from the class because spring documentation warns about this and is only allowed once in a row.

+10
source

I think you can achieve the same more easily by using ContentNegotiationManagerFactoryBean. By default, it first checks the extension of the URL path, and then the format property in the URL (for example .... / accounts? Format = pdf), and then the standard HTTP header property Accept. Using the format option is disabled by default.

 <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <property name="defaultContentType" value="text/html" /> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="pdf" value="application/pdf" /> <entry key="pdf" value="text/html" /> </map> </property> </bean> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="contentNegotiationManager" ref=""/> </bean> 

If you are using the JavaBeans Activation Framework, JAF, you do not need the mediaTypes section. Just put activ.jar in the classpath.

Did you try to do this, and did you also get class exceptions?

0
source

Well, you pointed out basically that Spring has no way to convert the string you provided, such as "application / pdf", to MediaType objects. I assume that the ContentNegotiationViewResolver has changed its mediaTypes map as map to map. You can try something like this:

 <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="pdf"> <value> <bean class="org.springframework.http.MediaType"> <constructor-arg value="application/pdf" /> </bean> </value> </entry> <entry key="html"> <value> <bean class="org.springframework.http.MediaType"> <constructor-arg value="text/html" /> </bean> </value> </entry> <entry key="json"> <value> <bean class="org.springframework.http.MediaType"> <constructor-arg value="application/json" /> </bean> </value> </entry> </map> </bean> 

Note. I did it from memory, so maybe it saddened it. Basically, you need entry values ​​for MediaTypes, not strings.

-1
source

All Articles