Spring REST 3支持XML和JSON

Adi*_*ing 5 java rest xstream spring-mvc jackson

如果我们使用Spring MVC开发REST,它将支持XML和JSON数据.我在spring config bean中编写了ContentNegotiationViewResorverapp-servlet.xml

<bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"
        p:order="1">
        <property name="mediaTypes">
            <map>
                <entry key="xml" value="application/xml" />
                <entry key="json" value="application/json" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <property name="marshaller">
                        <bean class="org.springframework.oxm.xstream.XStreamMarshaller"
                            p:autodetectAnnotations="true" />
                    </property>
                </bean>
                <bean
                    class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            </list>
        </property>
    </bean>
Run Code Online (Sandbox Code Playgroud)

我的Spring REST控制器是:

@Controller
@RequestMapping("/rest/customers")
class CustomerRestController {

protected Log log = LogFactory.getLog(CustomerRestController.class);

@RequestMapping(method = POST)
@ResponseStatus(CREATED)
public void createCustomer(@RequestBody Customer customer,
        HttpServletResponse response) {

    log.info(">>>" + customer.getName());
    response.setHeader("Location", String.format("/rest/customers/%s",
            customer.getNumber()));
}


@RequestMapping(value = "/{id}", method = GET)
@ResponseBody
public Customer showCustomer(@PathVariable String id) {
    Customer c = new Customer("0001", "teddy", "bean");
    return c;
}


@RequestMapping(value = "/{id}", method = PUT)
@ResponseStatus(OK)
public void updateCustomer(@RequestBody Customer customer) {
    log.info("customer: " + customer.getName());
}
Run Code Online (Sandbox Code Playgroud)

@XStreamAlias("customer")在我的客户域类中设置了注释.但是当我尝试访问http://localhost:8080/rest/customers/teddy.xml它时总是响应JSON数据.

@XmlRootElement(name="customer")在我的客户域类中设置了注释.但是当我尝试访问http://localhost:8080/rest/customers/teddy.json它时总是响应XML数据.

有什么不对 ?

Bij*_*men 2

我认为“xml”内容类型应该映射到“text/xml”而不是“application/xml”。另外,要强制基于扩展的内容类型解析器,您可以尝试将“ContentNegotiatingViewResolver”的“favorPathExtension”属性设置为 true(尽管默认情况下应该为 true!)

编辑:我现在已经在此 GIT 位置添加了一个工作示例 - git://github.com/bijukunjummen/mvc-samples.git,如果您使用 mvn tomcat:run 启动端点,则 json 位于http://localhost:8080/mvc-samples/rest/customers/teddy.json,xml 位于http://localhost:8080/mvc-samples/rest/customers/teddy.xml。这使用 JAXB2 而不是 XStream,因为我熟悉 JAXB。我注意到的一件事是,当我的 JAXB 注释在 Customer 类中不正确时,Spring 会按照您所看到的方式提供 JSON 而不是 XML(您可以通过从 Customer 类中删除 XMLRootElement 注释来复制它),一旦我修复了我的注释,我按预期返回了 XML。因此,您的 XStream 配置可能有问题。

编辑2:你是对的!我没有注意到,一旦我返回 xml,我就认为 json 现在可以工作了。我看到了问题,在 中AnnotationMethodHandlerAdapter,对 的处理@ResponseBody有点奇怪,它完全忽略了 ViewResolvers,并使用注册的 MessageConverters 而不是完全绕过ContentNegotiatingViewResolver,目前的一种解决方法是使用@ModelAttribute注释来响应,而不是 @ResponseBody,这样查看解析器被调用。现在尝试使用该项目git@github.com:bijukunjummen/mvc-samples.git,看看它是否适合您。这可能是 Spring 的错误,您可以尝试在 Spring 论坛中提出它,看看他们有什么建议。