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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With