Spring 3.2 content negotiation class cast exception

放肆的年华 提交于 2019-12-03 00:44:54
Sridhar

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!