将xml发布到Spring REST服务器返回不支持的媒体类型

时间:2010-03-08 22:03:23

标签: java spring rest spring-mvc jaxb

我正在尝试创建一个简单的基于Spring的Web服务,它支持带有xml内容的“帖子”。

在Spring中,我定义了一个AnnotationMethodHandler:

<bean id="inboundMessageAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <util:list>
                <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
                    <property name="marshaller" ref="xmlMarshaller"/>
                    <property name="unmarshaller" ref="xmlMarshaller"/>
                </bean>
            </util:list>
        </property>
    </bean>

基于jaxb的xml marshaller:

<bean id="xmlMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPaths">
            <array>
                <value>com.company.schema</value>
            </array>
        </property>
        <property name="schemas">
            <array>
                <value>classpath:core.xsd</value>
            </array>
        </property>
    </bean>

我的控制器注释如下,其中“Resource”是由jaxb自动生成的类:

@RequestMapping(method = POST, value = "/resource")
    public Resource createResource(@RequestBody Resource resource) {
       // do work
    }

Web服务调用的结果始终为“HTTP / 1.1 415 Unsupported Media Type”。这是一个示例服务调用:

HttpPost post = new HttpPost(uri);
post.addHeader("Accept", "application/xml");
post.addHeader("Content-Type", "application/xml");

StringEntity entity = new StringEntity(request, "UTF-8");
entity.setContentType("application/xml");
post.setEntity(entity);

在我看来,我正在设置正确的媒体类型。有人有想法吗?

编辑:在进一步调试之后,它似乎永远不会尝试解组该对象。我不太了解AnnotationMethodHandler如何知道application / xml类型应该发送到MarshallingHttpConverter背后的黑魔法。任何人都可以对此有所了解吗?

1 个答案:

答案 0 :(得分:6)

最可能的原因是JAXB上下文不知道如何解组Resource对象。

Resource是否有@XMLRootElement注释?如果没有,则Jaxb2Marshaller将不接受该参数,您将收到415错误。这是通过从Sprng委托给JAXB运行时完成的,Spring在这件事上并没有多少发言权。

修改@RequestBody参数的实际强制执行是在HandlerMethodInvoker.resolveRequestBody()中完成的。在匹配之前必须满足许多条件,包括MIME类型和参数类类型的匹配,如果失败,则没有日志记录,只有HTTP 415.查看该方法的源代码,更好的是,进行一些远程调试,以查看逻辑设置失败的位置。