【问题标题】:Spring MVC XML request returns 406 errorSpring MVC XML 请求返​​回 406 错误
【发布时间】:2014-07-03 10:48:43
【问题描述】:

我已经访问了所有论坛帖子,但仍然无法解决我的问题。我有一个应该返回 XML 和 JSON 结果的应用程序。但只有 JSON 有效,XML 请求返​​回 406 错误。我正在使用 Spring 3.2。除了 406 http 状态外,日志中没有错误。我尝试了以下配置:

配置1

<beans...>

    <context:component-scan base-package="com.sample" />


    <!-- First version -->
    <bean id="xmlConverter"
        class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
        <constructor-arg>
            <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                <property name="classesToBeBound">
                    <list>
                        <value>com.sample.Class</value>
                    </list>
                </property>
            </bean>

        </constructor-arg>
        <property name="supportedMediaTypes">
            <list>
                <bean class="org.springframework.http.MediaType">
                    <constructor-arg index="0" value="application" />
                    <constructor-arg index="1" value="xml" />
                    <constructor-arg index="2" value="UTF-8" />
                </bean>
            </list>
        </property>
    </bean>

    <bean id="jaxbAnnotationInspector" class="org.codehaus.jackson.xc.JaxbAnnotationIntrospector" />
    <bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper">
        <property name="annotationIntrospector" ref="jaxbAnnotationInspector" />
    </bean>
    <bean id="jsonConverter"
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="objectMapper" ref="jacksonObjectMapper" />
        <property name="supportedMediaTypes">
            <list>
                <bean class="org.springframework.http.MediaType">
                    <constructor-arg index="0" value="application" />
                    <constructor-arg index="1" value="json" />
                    <constructor-arg index="2" value="UTF-8" />
                </bean>
            </list>
        </property>
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="xmlConverter" />
                <ref bean="jsonConverter" />
            </list>
        </property>
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="useDefaultSuffixPattern" value="false" />
    </bean>
</beans>

配置2

<beans ...>

    <context:component-scan base-package="com.sample" />

    <mvc:annotation-driven />

    <!-- Second version -->
    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="defaultContentType" value="application/xml" />
        <property name="mediaTypes">
            <map>
                <entry key="xml" value="application/xml" />
                <entry key="json" value="application/json" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                    <property name="prefixJson" value="false" />
                </bean>
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <constructor-arg>
                        <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                            <property name="classesToBeBound">
                                <list>
                                    <value>com.sample.Class</value>
                                </list>
                            </property>
                        </bean>
                    </constructor-arg>
                </bean>
            </list>
        </property>
        <property name="favorPathExtension" value="true" />
        <property name="ignoreAcceptHeader" value="false" />
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="useDefaultSuffixPattern" value="false" />
    </bean>
</beans>

我的 Maven 依赖项:

<!-- Spring 3 dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${org.springframework.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>commons-logging</artifactId>
            <groupId>commons-logging</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${org.springframework.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${org.springframework.version}</version>
    <scope>compile</scope>
</dependency>

<!-- Jackson JSON Mapper -->
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.10</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
    <version>1.9.10</version>
</dependency>

<!-- XML Mapper -->
<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-oxm-tiger</artifactId>
    <version>1.5.10</version>
</dependency>

我的方法:

@RequestMapping(value = "/repositories", method = RequestMethod.GET)
@ResponseBody
public List<Repository> getRepositories(HttpServletRequest req, HttpServletResponse resp) throws CaraException {
    List<Repository> repositories = repositoryFactory.getAvailableRepositories();
    return repositories;
}

我的班级用 JAXB 注释:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Repository

[编辑]

我缩小了问题的范围。看起来它与我返回的 java.util.List 有关。如果我尝试返回使用 JAXB 注释的任何其他对象 - 它可以工作。所以问题是如何使 List 工作?

在此先感谢您提供任何帮助。

马吕斯

【问题讨论】:

  • 您希望返回的对象是否使用 JAXB 正确注释?
  • 是的,@RequestMapping(value = "/repositories", method = RequestMethod.GET) @ResponseBody public List&lt;Repository&gt; getRepositories(HttpServletRequest req, HttpServletResponse resp) throws CaraException { List&lt;Repository&gt; repositories = repositoryFactory.getAvailableRepositories(); return repositories; }@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Repository
  • 删除所有内容,只留下&lt;mvc:annotation-driven /&gt;&lt;context:component-scan /&gt; 其他所有内容都将被自动检测。
  • 您只能返回单个根元素而不是集合。例如,您必须将其包装在 Repositories 类中。 List 不适用于 JAXB。

标签: java xml json spring spring-mvc


【解决方案1】:

我找到了解决方案。而不是 List 我必须创建一个列表包装器并返回该包装器。显然 JAXB 无法处理列表。

@XmlRootElement(name = "repositories")
public class RepositoryListWrapper {
    private List<Repository> list;

    protected RepositoryListWrapper() {
    } // Keep JAXB happy

    public RepositoryListWrapper(List<Repository> list) {
        this.list = list;
    }

    @XmlElement(name = "repository")
    public List<Repository> getRepositories() {
        return list;
    }
}

【讨论】:

  • XmlRootElement的名字不应该和类名一样吗?
猜你喜欢
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 2020-11-21
相关资源
最近更新 更多