We develop a standard Java web application using Spring MVC, and have recently tried to upgrade from 3.0.6 to 3.2.0. Nearly of all our servlet responses are JSP or Json views, b
I think you can achieve the same thing more easily using the ContentNegotiationManagerFactoryBean. By default it checks the URL path extension first, then a format property in the URL (such as ..../accounts?format=pdf) and then the standard HTTP Accept header property. The use of the format parameter is off 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 use the JavaBeans Activation Framework, JAF, you shouldn't need the mediaTypes section. Just put activation.jar on the classpath.
Did you try this and did you also get class-cast exceptions?
Well, the error you posted is basically saying that Spring doesn't have a way to convert the string you provided, for example "application/pdf", to the MediaType objects. I am guessing the ContentNegotiatingViewResolver changed it's mediaTypes map to be a Map to a Map. You could 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 this from memory, so I may have typo'd this. Basically, you need the entry values to be MediaTypes, not strings.
With spring 3.2 it is better resolved using ContentNegotiationManager. It is working for me. You could use the static field like org.springframework.http.MediaType.APPLICATION_JSON_VALUE to mention the mediatype. 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>
For this you have to use util schema in your dispatcher-servlet.xml file, i.e. xmlns:util="http://www.springframework.org/schema/util" and schema location http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
I fixed the problem by removing duplicated
<mvc:annotation-driven/> from xml-configuration
or
@EnableWebMVC annotation from the class
because spring documentation warns about that and allowed only once by contract.