Я пытаюсь создать простой основанный на пружине веб-сервис, который поддерживает "сообщение" с содержанием XML.
Пружиной я определяю 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>
Мой контроллер аннотируется следующим образом, где "Ресурс" является классом, автоматически сгенерированным jaxb:
@RequestMapping(method = POST, value = "/resource")
public Resource createResource(@RequestBody Resource resource) {
// do work
}
Результатом вызова веб-сервиса всегда является "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 знает, что что-то вроде приложения типа/xml должно перейти к MarshallingHttpConverter. Кто-либо может пролить какой-либо свет на это?
Наиболее вероятная причина в том, что контекст JAXB не знает, как демаршалировать объект Resource
.
Есть ли у ресурса
аннотация @XMLRootElement
? Если нет, то Jaxb2Marshaller
не примет параметр, и вы получите ошибку 415. Это делается путем делегирования от Sprng к среде выполнения JAXB, Spring на самом деле не имеет особого отношения к этому вопросу.
edit : Фактическое приведение данных к параметру @RequestBody
выполняется в HandlerMethodInvoker.resolveRequestBody ()
. Существует целый ряд условий, которые должны быть выполнены перед тем, как будет выполнено сопоставление, включая сопоставление типа MIME и типа класса параметров, и если это не удается, журнала не ведется, только HTTP 415. Взгляните на источник для этого метода. , а еще лучше, выполните удаленную отладку, чтобы увидеть, где логика не работает в вашей настройке.