2011-01-31 21 views
23

Chiedo scusa per aver postato questa domanda noob, ma ho risolto il problema da un po 'di tempo. Sto avendo un piccolo problema cercando di ottenere la risposta per restituire l'XML in base all'oggetto: -Spring MVC 3: ritorno XML tramite @ResponseBody

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

In questo momento, anche se questa API viene chiamata, il mio lato client non riceve la risposta XML a tutti . Ho letto alcuni posti e sembra che ho bisogno di configurare il marshaller XML o il somesort dei resolver XML, ma non sono sicuro di come integrare quel pezzo nella mia configurazione esistente. Al momento ho la seguente configurazione nel mio 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> 

Qualcuno può gentilmente inviare alcune configurazioni di esempio su come potrei andare circa nella configurazione mia servlet.xml per ottenere questo lavoro? Grazie mille.

risposta

22

Questo può essere fatto aggiungendo la seguente po 'di magia al contesto della molla (vedi docs):

<mvc:annotation-driven/> 

che tra le altre cose, prevede quanto segue:

supporto per la lettura e la scrittura di XML , se JAXB è presente sul classpath.

Se viene rilevato JAXB (cioè se siete su java6, o comunque avere qualche implementazione JAXB sul classpath), questo registrerà un Jaxb2RootElementHttpMessageConverter con il contesto, e fornirà la capacità di sputare XML dal valore restituito del metodo annotato @ResponseBody.

Nota: il tipo di domanda suggerisce di utilizzare uno ViewResolver per il rendering dell'XML, ma questo non è necessario. L'annotazione @ResponseBody è progettata per aggirare completamente il livello di visualizzazione.

+0

Concordato sul gonfiarsi. Spring ha bisogno di una soluzione pronta per questo. È ridicolo. – sourcedelica

+0

@ericacm: Ho dovuto ripensarci e sono andato a guardare il codice sorgente (e * quindi * rileggere la documentazione), ed è molto più semplice di quanto pensassi. Vedi modifica. – skaffman

+0

Ho jaxb-api-xx.jar nel classpath, ma sembra che non stia facendo nulla. Dovrei annotare le proprietà della classe 'SomeObject' con le annotazioni di JAXB perché funzioni? – limc

7

quello che faccio quando voglio tornare una rappresentazione XML di oggetti utilizzando la primavera è che io definisco un MarshallingView, per esempio,

<!-- 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"/> 

Nota che c'è un intero mondo di alternatives a JAXB. Il passo successivo è

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

Oppure, se si desidera utilizzare l'annotazione responseBody, sarebbe simile:

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

Si noti che questo richiede la definizione di una HttpMessageConverter. Vedere la documentazione spring per un esempio perfetto su come farlo.

+0

E 'possibile effettuare un metodo che restituisce un "viewname" o @ResponseBody? – trusktr

15

Ho risolto questo problema con la Spring 3 MVC senza 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); 
} 

questo è tutto.saluti

2

Prova ad aggiungere produces = MediaType.APPLICATION_XML_VALUE, cioè

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

Aggiunta produces = MediaType.APPLICATION_XML_VALUE al RequestMapping e @XmlRootElement alla parte superiore del vostro oggetto modello dovrebbe funziona

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

@XmlRootElement 
public class SomeObject { 

} 
Problemi correlati