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, чтобы это работало? Большое спасибо.
6 ответов
Это можно сделать, добавив следующую магию в контекст Spring (см. Документы):
<mvc:annotation-driven/>
который, помимо прочего, обеспечивает:
Поддержка чтения и записи XML, если JAXB присутствует в пути к классам.
Если обнаружен JAXB (т. Е. Если вы находитесь на Java6, или у вас есть какая-либо реализация JAXB на вашем пути к классам), это зарегистрирует Jaxb2RootElementHttpMessageConverter
с контекстом, и предоставит возможность выплюнуть XML из возвращаемого значения @ResponseBody
Аннотированный метод.
Примечание: ваш вопрос вроде как предложил использовать ViewResolver
для рендеринга XML, но это не обязательно. @ResponseBody
аннотация предназначена для полного обхода слоя представления.
Я решил эту проблему с 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);
}
это все. Привет
Когда я хочу вернуть 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"/>
Обратите внимание, что существует целый мир альтернатив jaxb. Следующий шаг
@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. См. Весеннюю документацию для идеального образца того, как это сделать.
Вам, вероятно, придется либо использовать XML Marshalling View, либо настроить MarshallingHttpMessageConverter
,
Вот краткое руководство по использованию@ResponseBody
с конвертерами.
Попробуйте добавить produces = MediaType.APPLICATION_XML_VALUE
т.е.
@RequestMapping(value = "/mylink", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
Добавление 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 {
}