简体   繁体   中英

post xml to Spring REST server returns Unsupported Media Type

I'm trying to create a simple spring based webservice that supports a "post" with xml content.

In spring, I define an 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>

And a jaxb based 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>

My controller is annotated as follows, where "Resource" is a class autogenerated by jaxb:

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

The result of a webservice call is always "HTTP/1.1 415 Unsupported Media Type". Here is an example service call:

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

It seems to me that I am setting the correct media type everywhere possible. Anyone have an ideas?

Edit: after further debugging, it looks as though it never gets as far as trying to unmarshal the object. I don't quite understand the black magic behind how the AnnotationMethodHandler knows that something of type application/xml should go to the MarshallingHttpConverter. Can anyone shed any light on that?

The most likely reason is that the JAXB context doesn't know how to unmarshal to a Resource object.

Does Resource have an @XMLRootElement annotation? If not, then Jaxb2Marshaller will not accept the parameter, and you'll get the 415 error. This is done by delegation from Sprng to the JAXB runtime, Spring doesn't really have much say in the matter.

edit : The actual coercion of the data on to the @RequestBody parameter is done in HandlerMethodInvoker.resolveRequestBody() . There are quite a number of conditions that must be met before the match is made, including matching of MIME type and parameter class type, and if it fails, there's no logging, just the HTTP 415. Have a look at the source for that method, and better yet, do some remote debugging to see where the logic is failing for your setup.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM