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.