春季3.2内容协商类转换异常(Spring 3.2 content negotiation clas

2019-08-16 16:52发布

我们开发使用Spring MVC标准的Java Web应用程序,并在最近试图从升级到3.0.6 3.2.0。 几乎我们所有的servlet响应的是JSP或JSON的观点,但也有一些是PDF格式的要求,具有扩展名“PDF”。

在Spring 3.0.6,我们有这个设置,从Spring MVC资料为准。

<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>

这工作得很好,结合一个XMLViewResolver。

更新到3.2.0之后,有一项不合格:

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'

调查文档和一些博客后,这个配置似乎工作:

<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>

但是,我们已经尝试使用这个配置运行新的Spring MVC的测试框架,并再次获得ClassCast异常,因此它似乎在测试框架而不是应用程序运行时的初始化豆以同样的方式...有谁有如何在一个强大的方式配置在Spring 3,2 ContentNegotiatingViewResolver解释清楚? 谢谢

理查德

Answer 1:

随着春天3.2则使用更好的解决ContentNegotiationManager 。 这是为我工作。 您可以使用静态字段一样org.springframework.http.MediaType.APPLICATION_JSON_VALUE提介质类型。 检查下面的代码:

<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>

对于这一点,你必须使用util的模式在您的调度员-servlet.xml文件,即xmlns:util="http://www.springframework.org/schema/util"和架构位置http://www.springframework.org/架构/ UTIL http://www.springframework.org/schema/util/spring-util-3.0.xsd



Answer 2:

我固定通过去除问题复制<mvc:annotation-driven/>从XML配置或@EnableWebMVC从类注释因为弹簧文档警告有关并在签订合同只允许一次。



Answer 3:

我觉得你可以更轻松地实现同样的事情用ContentNegotiationManagerFactoryBean。 缺省情况下它首先检查URL路径扩展,然后在URL的格式属性(例如.... /帐户?格式= PDF),然后将标准的HTTP Accept报头属性。 使用format参数的默认是关闭的。

<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>

如果你使用JavaBeans激活框架,JAF,你不应该需要mediaTypes部分。 只要把的activation.jar类路径上。

你试试这个?你还可以获得类强制转换异常?



Answer 4:

那么,您发布的错误基本上是说,春季没有办法提供给您的字符串转换,例如“应用程序/ PDF格式”,给的MediaType对象。 我猜ContentNegotiatingViewResolver改变它的mediaTypes映射是一个映射到地图。 你可以尝试这样的事:

<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>

注:我这样做从内存,所以我可能typo'd这一点。 基本上,你需要的项值是MediaTypes,而不是字符串。



文章来源: Spring 3.2 content negotiation class cast exception