Spring MVC 3:通过 @ResponseBody 返回 XML

Posted

技术标签:

【中文标题】Spring MVC 3:通过 @ResponseBody 返回 XML【英文标题】:Spring MVC 3: Returning XML through @ResponseBody 【发布时间】:2011-06-18 21:12:08 【问题描述】:

请原谅我发布这个菜鸟问题,但我已经调试这个问题很长一段时间了。我在尝试获取基于对象返回 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 以使其正常工作吗?非常感谢。

【问题讨论】:

【参考方案1】:

这可以通过在 Spring 上下文中添加以下魔法来完成(参见 docs):

<mvc:annotation-driven/>

其中包括:

如果类路径中存在 JAXB,则支持读取和写入 XML。

如果检测到 JAXB(即,如果您在 Java6 上,或者在您的类路径上有一些 JAXB 实现),这将在上下文中注册一个 Jaxb2RootElementHttpMessageConverter,并提供从返回中吐出 XML 的能力@ResponseBody-annotated 方法的值。

注意:您的问题有点建议使用ViewResolver 来呈现 XML,但这不是必需的。 @ResponseBody 注解旨在完全绕过视图层。

【讨论】:

同意膨胀。 Spring 需要为此提供开箱即用的解决方案。这太荒谬了。 @ericacm:我重新考虑了一下,然后去查看了源代码(然后重新阅读了文档),这比我要容易得多第一个想法。见编辑。 我在类路径中有 jaxb-api-xx.jar,但它似乎没有做任何事情。我是否应该使用 JAXB 的注释来注释 SomeObject 类属性以使其正常工作? 除了添加 jaxb-api.jar 和 jaxb-impl.jar(我正在使用 Java5),我还必须用 @XmlRootElement 注释 SomeObject... 然后一切都像一个魅力.感谢您的帮助! 如果我返回对象列表,它会自动转换为 json。如何强制始终使用 xml? (也张贴在tinyurl.com/3qqycu9)【参考方案2】:

我用没有 MarshallingView 的 Spring 3 mvc 解决了这个问题

@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);

就是这样。问候

【讨论】:

【参考方案3】:

当我想使用 spring 返回对象的 XML 表示时,我会定义一个 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,alternatives 是一个完整的世界。 下一步是

@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 文档。

【讨论】:

是否可以创建一个返回“viewname”或@ResponseBody 的方法?【参考方案4】:

您可能必须使用XML Marshalling View 或配置MarshallingHttpMessageConverter

这是一个简短的Reference about using @ResponseBody with converters。

【讨论】:

【参考方案5】:

尝试添加produces = MediaType.APPLICATION_XML_VALUE,即

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

【讨论】:

【参考方案6】:

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 


【讨论】:

以上是关于Spring MVC 3:通过 @ResponseBody 返回 XML的主要内容,如果未能解决你的问题,请参考以下文章

spring mvc 是不是有 response.write 可以直接输出到浏览器?

Spring MVC 中获取 HttpServletRequest request, HttpServletResponse response 对象的方法

Spring MVC (Java),强制页面不缓存

在 Spring MVC 中以 AJAX 响应发送文件

springmvc怎么设置相应头信息

Spring mvc 判断用户是不是存在