2011-01-31 29 views
23

Perdónenme por publicar esta pregunta de novato, pero he estado depurando este problema por bastante tiempo. Estoy teniendo un pequeño problema tratando de obtener la respuesta para devolver el XML basado en el objeto: -Spring MVC 3: Devolver XML a través de @ResponseBody

@RequestMapping(value = "/mylink", method = RequestMethod.GET) 
public @ResponseBody SomeObject doIt() { 
    ... 
} 

En este momento, a pesar de que la API se llama, mi lado cliente no recibe la respuesta XML en absoluto . He estado leyendo algunos lugares y parece que necesito configurar el marcador de XML o una serie de resolvedores XML, pero no estoy seguro de cómo integrar esa pieza en mi configuración existente. En este momento tengo la siguiente configuración en mi servlet.xml: -

<context:component-scan base-package="ss.controller" /> 

<mvc:annotation-driven /> 

<mvc:resources location="/resources/" mapping="/resources/**" /> 

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="prefix" value="/WEB-INF/jsp/app/" /> 
    <property name="suffix" value=".jsp" /> 
</bean> 

Puede alguien amablemente publicar algunas configuraciones de ejemplo sobre cómo podría ir sobre la hora de configurar mi servlet.xml a conseguir este trabajo? Muchas gracias.

Respuesta

22

Esto se puede hacer mediante la adición de la siguiente poco de magia para el contexto de Primavera (ver docs):

<mvc:annotation-driven/> 

que, entre otras cosas, dispone:

soporte para leer y escribir XML , si JAXB está presente en el classpath.

Si se detecta JAXB (es decir, si se encuentra en java6, o de otra manera tener alguna aplicación JAXB en su ruta de clase), esto va a registrar un Jaxb2RootElementHttpMessageConverter con el contexto, y proporcionará la capacidad de escupir XML desde el valor de retorno del @ResponseBody, método anotado.

Nota: Su pregunta sugirió el uso de un ViewResolver para procesar el XML, pero esto no es necesario. La anotación @ResponseBody está diseñada para omitir la capa de vista por completo.

+0

De acuerdo sobre la hinchazón. Spring necesita tener una solución lista para usar para esto. Es ridículo. – sourcedelica

+0

@ericacm: Pensé en esto y revisé el código fuente (y * luego * volví a leer la documentación), y es mucho más fácil de lo que pensé en un principio. Ver editar. – skaffman

+0

Tengo jaxb-api-xx.jar en el classpath, pero no parece estar haciendo nada. ¿Se supone que debo anotar las propiedades de la clase 'SomeObject' con las anotaciones de JAXB para que esto funcione? – limc

7

lo que hago cuando quiero devolver una representación XML de los objetos utilizando la primavera es que defino un MarshallingView, por ejemplo,

<!-- XML view using a JAXB marshaller --> 
<bean id="jaxbView" class="org.springframework.web.servlet.view.xml.MarshallingView"> 
    <constructor-arg> 
     <bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
      <property name="classesToBeBound"> 
       <list> 
        <value>com.company.AClass</value> 
       </list> 
      </property> 
     </bean> 
    </constructor-arg> 
</bean> 

<!-- Resolve views based on string names --> 
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/> 

en cuenta que hay todo un mundo de alternatives a jaxb. El siguiente paso es

@RequestMapping("/request") 
public ModelAndView sample() { 
    return new ModelAndView("jaxbView", "data", "data_to_be_turned_into_xml"); 
} 

O si desea utilizar la anotación responseBody, que se vería así:

@RequestMapping("/request") 
@ResponseBody 
public void sample() { 
    return "data_to_be_turned_into_xml" 
} 

Tenga en cuenta que esto requiere la definición de un HttpMessageConverter. Consulte la documentación spring para obtener una muestra perfecta sobre cómo hacer esto.

+0

¿Es posible hacer un método que devuelve un "viewname" o un @ResponseBody? – trusktr

15

He resuelto este problema con Spring 3 MVC sin MarshallingView

@RequestMapping(value = "actionName.xml", method = RequestMethod.GET) 
public HttpEntity<byte[]> getXml(ModelMap map, HttpServletResponse response) { 

    String xml = generateSomeXml(); 

    byte[] documentBody = xml.getBytes(); 

    HttpHeaders header = new HttpHeaders(); 
    header.setContentType(new MediaType("application", "xml")); 
    header.setContentLength(documentBody.length); 
    return new HttpEntity<byte[]>(documentBody, header); 
} 

eso es todo.saludos

2

Trate de añadir produces = MediaType.APPLICATION_XML_VALUE, es decir

@RequestMapping(value = "/mylink", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE) 
0

Adición produces = MediaType.APPLICATION_XML_VALUE a la RequestMapping y @XmlRootElement a la parte superior de su objeto modelo debe funciona

@RequestMapping(value = "/mylink", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE) 
public SomeObject doIt(){ 
    return new SomeObject(); 
} 

@XmlRootElement 
public class SomeObject { 

} 
Cuestiones relacionadas