向Spring REST服务器发送XML返回“不支持的媒体类型”错误

7

我将尝试创建一个基于Spring的简单Web服务,支持使用XML内容进行“post”请求。

在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编组器:

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

调用webservice的结果总是“HTTP/1.1 415不支持的媒体类型”。下面是一个示例服务调用:

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个回答

6
最有可能的原因是JAXB上下文不知道如何将数据反序列化为Resource对象。
如果Resource没有@XMLRootElement注解,那么Jaxb2Marshaller将无法接受该参数,您将收到415错误。这是通过从Spring委托给JAXB运行时来完成的,Spring在这方面并没有太多发言权。 编辑:实际上,将数据强制转换为@RequestBody参数是在HandlerMethodInvoker.resolveRequestBody()中完成的。在进行匹配之前,必须满足许多条件,包括MIME类型和参数类类型的匹配,如果失败,则没有日志记录,只会返回HTTP 415。请查看该方法的源代码,最好进行远程调试,以确定逻辑在您的设置中失败的位置。

感谢您的建议,skaffman。我检查了一下,这个类确实有一个@XMLRootElement标签。 - Cheryl Simon
@Mayra:Resourcecom.company.schema 包中吗?尝试编写一个单元测试,使用您的配置构造一个 Jaxb2Marshaller,并确保 support(Resource.class) 返回 true。在您能够进一步操作之前,这是必须要工作的。 - skaffman
不行,我创建了一个Jaxb2Marshaller对象,设置了与Spring文件中相同的contextPath和schema,并且它显示支持我的类。 - Cheryl Simon
@skaffman:谢谢,这让我找到了正确的答案!事实证明,这与配置无关,在服务器中的另一个AnnotationMethodHandler定义与我的定义冲突。 - Cheryl Simon
@Mayra:很高兴听到这个消息。它一定在里面 :) - skaffman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接