Spring 3.2 content negotiation class cast exception

后端 未结 4 1209
青春惊慌失措
青春惊慌失措 2021-02-04 21:21

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

相关标签:
4条回答
  • 2021-02-04 21:58

    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?

    0 讨论(0)
  • 2021-02-04 22:07

    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.

    0 讨论(0)
  • 2021-02-04 22:11

    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

    0 讨论(0)
  • 2021-02-04 22:14

    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.

    0 讨论(0)
提交回复
热议问题