2010-03-08 18 views
6

Estoy intentando crear un servicio web simple basado en resortes que admita una "publicación" con contenido xml.publicar xml en el servidor REST de Spring devuelve Tipo de medio no admitido

En la primavera, defino un 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> 

Y un jaxb basado marshaller 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> 

Mi controlador está anotado como sigue, donde "recurso" es una clase autogenerada por jaxb :

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

El resultado de una llamada al servicio web siempre es "HTTP/1.1 415 No soportado Med ia Tipo ". Aquí hay una llamada de servicio de ejemplo:

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

Me parece que estoy configurando el tipo de medio correcto en todos los lugares posibles. Alguien tiene ideas?

Editar: después de una nueva depuración, parece como si nunca llegara a tratar de destrabar el objeto. No entiendo muy bien la magia negra detrás de cómo AnnotationMethodHandler sabe que algo del tipo application/xml debería ir al MarshallingHttpConverter. ¿Alguien puede arrojar algo de luz sobre eso?

Respuesta

5

La razón más probable es que el contexto de JAXB no sepa cómo deshacerse de un objeto Resource.

¿Tiene Resource una anotación @XMLRootElement? Si no, entonces Jaxb2Marshaller no aceptará el parámetro, y obtendrá el error 415. Esto se hace por delegación de Sprng al tiempo de ejecución JAXB, Spring realmente no tiene mucho que decir al respecto.

edición: La coerción real de los datos sobre el parámetro a @RequestBody se realiza en HandlerMethodInvoker.resolveRequestBody(). Hay muchas condiciones que se deben cumplir antes de realizar la coincidencia, incluida la coincidencia del tipo MIME y el tipo de clase de parámetro, y si falla, no hay registro, solo el HTTP 415. Eche un vistazo a la fuente de ese método , y mejor aún, realice alguna depuración remota para ver dónde falla la lógica de su configuración.

+0

Gracias por la sugerencia, skaffman. Compruebo y la clase sí tiene una etiqueta @XMLRootElement. –

+0

@Mayra: ¿Y 'Recurso' está en el paquete' com.company.schema'? Intenta escribir una prueba unitaria que construya un 'Jaxb2Marshaller' con tu configuración, y asegúrate de que' support (Resource.class) 'devuelva' true'. Eso debe funcionar antes de que puedas llegar más lejos. – skaffman

+0

Sin dados, creé un objeto Jaxb2Marshaller, configuré el contexto y el esquema como lo hice en mi archivo de primavera, y dice que admite mi clase. –

Cuestiones relacionadas