Spring MVC 3: возврат XML через @ResponseBody

Простите меня за публикацию этого нубского вопроса, но я уже довольно давно отлаживаю эту проблему. У меня небольшая проблема с попыткой получить ответ, чтобы вернуть XML на основе объекта: -

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

Прямо сейчас, несмотря на то, что этот API вызывается, моя клиентская сторона вообще не получает ответ XML. Я читал несколько мест, и мне кажется, что мне нужно настроить маршаллер XML или какие-то преобразователи XML, но я не уверен, как интегрировать эту часть в мою существующую конфигурацию. В настоящее время у меня есть следующая конфигурация в моем 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>

Может ли кто-нибудь опубликовать несколько примеров конфигураций о том, как я могу настроить свой servlet.xml, чтобы это заработало? Спасибо большое.


person limc    schedule 31.01.2011    source источник


Ответы (6)


Это можно сделать, добавив в контекст Spring следующее волшебство (см. документы):

<mvc:annotation-driven/>

который среди прочего обеспечивает:

Поддержка чтения и записи XML, если в пути к классам присутствует JAXB.

Если JAXB обнаружен (например, если вы используете Java6 или иным образом имеете некоторую реализацию JAXB в своем пути к классам), это зарегистрирует Jaxb2RootElementHttpMessageConverter с контекстом и предоставит возможность выдать XML из возвращаемого значения @ResponseBody- аннотированный метод.

Примечание. В вашем вопросе предлагается использовать ViewResolver для рендеринга XML, но это не обязательно. Аннотация @ResponseBody предназначена для полного обхода уровня представления.

person skaffman    schedule 31.01.2011
comment
Про вздутие согласен. Для этого у Spring должно быть готовое решение. Это нелепо. - person sourcedelica; 01.02.2011
comment
@ericacm: я еще раз подумал об этом и пошел и посмотрел исходный код (и затем перечитал документацию), и это намного проще, чем я думал сначала. См. редактирование. - person skaffman; 01.02.2011
comment
У меня есть jaxb-api-xx.jar в пути к классам, но, похоже, он ничего не делает. Должен ли я аннотировать свойства класса SomeObject аннотациями JAXB, чтобы это работало? - person limc; 01.02.2011
comment
В дополнение к добавлению jaxb-api.jar и jaxb-impl.jar (я использую Java5), я должен аннотировать SomeObject с помощью @XmlRootElement... тогда все работает как шарм. Спасибо за вашу помощь! - person limc; 01.02.2011
comment
Ааа... Я совсем забыл об этом :) Это приятно и просто, как и должно быть. - person sourcedelica; 03.02.2011
comment
Если я верну список объектов, он автоматически преобразуется в json. Как заставить всегда использовать xml? (Также опубликовано на tinyurl.com/3qqycu9) - person kalyan; 07.09.2011

Я решил эту проблему с помощью Spring 3 mvc без 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);
}

это все. Привет

person otmek    schedule 06.02.2013

Что я делаю, когда хочу вернуть XML-представление объектов с помощью Spring, так это то, что я определяю MarshallingView, например,

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

Обратите внимание, что существует целый мир альтернатив для джаксб. Следующий шаг

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

Или, если вы хотите использовать аннотацию ResponseBody, это будет выглядеть так:

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

Обратите внимание, что для этого требуется определить HttpMessageConverter< /а>. См. документацию spring. для идеального образца о том, как это сделать.

person Johan Sjöberg    schedule 31.01.2011
comment
Можно ли создать метод, который возвращает имя представления или @ResponseBody? - person trusktr; 25.02.2014

Вам, вероятно, придется использовать ссылку XML Marshalling View или настроить MarshallingHttpMessageConverter.

Вот краткий Справка об использовании @ResponseBody с конвертерами.

person Sean Patrick Floyd    schedule 31.01.2011

Попробуйте добавить produces = MediaType.APPLICATION_XML_VALUE, т.е.

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

Добавление produces = MediaType.APPLICATION_XML_VALUE в RequestMapping и @XmlRootElement в верхнюю часть объекта вашей модели должно работать.

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

@XmlRootElement
public class SomeObject {

}
person Kamiel Ahmadpour    schedule 11.03.2017