web-dev-qa-db-fra.com

Spring MVC 3: renvoi de XML via @ResponseBody

Pardonnez-moi d’avoir posé cette question à Noob, mais cela fait un moment que je corrige ce problème. J'ai un petit problème à essayer d'obtenir la réponse pour renvoyer le XML basé sur l'objet: -

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

À l'heure actuelle, même si cette API est appelée, mon côté client ne reçoit pas la réponse XML. J'ai lu quelques endroits et il me semble que j'ai besoin de configurer le marshaller XML ou un certain nombre de résolveurs XML, mais je ne suis pas sûr de savoir comment intégrer cet élément dans ma configuration existante. J'ai actuellement la configuration suivante dans mon 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>

Quelqu'un peut-il avoir la gentillesse de poster quelques exemples de configurations sur la manière dont je pourrais procéder pour configurer mon servlet.xml afin que cela fonctionne? Merci beaucoup.

23
limc

Cela peut être fait en ajoutant la magie suivante au contexte Spring (voir docs ):

<mvc:annotation-driven/>

qui fournit entre autres:

Prise en charge de la lecture et de l'écriture XML, si JAXB est présent sur le chemin d'accès aux classes.

Si JAXB est détecté (c'est-à-dire si vous êtes sur Java6 ou si vous avez une implémentation JAXB sur votre chemin de classe), cela enregistrera un Jaxb2RootElementHttpMessageConverter avec le contexte et vous permettra de cracher du XML à partir de la valeur de retour du @ResponseBody- méthode annotée.

Remarque: votre question suggère en quelque sorte d'utiliser une variable ViewResolver pour restituer le code XML, mais cela n'est pas nécessaire. L'annotation @ResponseBody est conçue pour contourner complètement le calque de vue.

22
skaffman

J'ai résolu ce problème avec Spring 3 mvc sans 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);
}

c'est tout. salutations 

15
otmek

Ce que je fais lorsque je veux renvoyer une représentation XML d’objets à l’aide de spring, c’est que je définis un MarshallingView, par exemple, 

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

Notez qu'il existe un monde entier de alternatives à jaxb. La prochaine étape est

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

Ou si vous souhaitez utiliser l'annotation ResponseBody, cela ressemblerait à ceci: 

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

Notez que cela nécessite de définir un HttpMessageConverter . Voir la documentation spring pour un exemple parfait sur la façon de procéder. 

7
Johan Sjöberg
5
Sean Patrick Floyd

Essayez d’ajouter produces = MediaType.APPLICATION_XML_VALUE, c.-à-d.

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

Ajouter produces = MediaType.APPLICATION_XML_VALUE à RequestMapping et @XmlRootElement en haut de votre objet de modèle devrait fonctionner

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

@XmlRootElement
public class SomeObject {

}
0
Kamiel Ahmadpour