Spring REST 3支持XML和JSON

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

                   

我的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()); } 

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

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

有什么不对 ?

我认为“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 at 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,这种方式调用了Resolvers。 现在尝试使用git@github.com:bijukunjummen/mvc-samples.git的项目git@github.com:bijukunjummen/mvc-samples.git ,看看它是否适合你。 这可能是一个Spring bug,你可以尝试在Spring论坛中提出它,看看他们推荐什么。

什么Accept标头发送到您的服务器? 确保您要请求的内容类型位于此列表中。

Spring 3.1解决了你在@RequestMapping注释上使用new produces元素提到的问题。 这允许您控制Spring应用于对象的HttpMessageConverter

我写了一篇关于它的博客文章:

http://springinpractice.com/2012/02/22/supporting-xml-and-json-web-service-endpoints-in-spring-3-1-using-responsebody/

我有同样的问题。 我假设您使用的是Spring 3,并且您使用了 。 我不完全确定,但我认为这会根据mvc命名空间配置的消息转换器产生一些冲突。

使用oxm命名空间对我有用:

 @XmlRootElement(name="person") class Person { private String firstName; private String lastName; } @Controller @RequestMapping("person") class PersonController { @RequestMapping("list") public @ResponseBody Person getPerson() { Person p = new Person(); p.setFirstName("hello"); p.setLastName("world"); return p; } } 

内容配置(mvc和内部视图解析器在另一个上下文中):

                          

此示例使用JAXB,因此您需要在类路径上使用jaxb-api和jaxb-impl。

另外,只需一个提示,您不需要app-servlet.xml。 在您的web.xml中,将config设置为null并让Context Listener为您加载它们:

  org.springframework.web.context.ContextLoaderListener   contextConfigLocation /WEB-INF/spring/mvc-context.xml, /WEB-INF/spring/content-negotiation-context.xml   app org.springframework.web.servlet.DispatcherServlet  contextConfigLocation   1   app /  

好吧,我得到了一个解决方案,但我不知道它是否是你方法展示客户的正确方法:

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

在这一部分中,我们使用spring的MVC,在控制器中我们应该返回一个视图,所以我删除了注释@ResponseBody并返回一个带有视图名称的String ,因为在我们的XML中我们添加了一个ContentNegotiatingViewResolver ,当我们有ResponseBody ,contentnegociationviewresolver被忽略,因为正在等待视图,但我们返回了对象,所以方法应该是这样的:

 @RequestMapping(value = "/{id}", method = GET) public String showCustomer(@PathVariable String id, ModelMap model) { Customer c = new Customer("0001", "teddy", "bean"); model.addAttribute("customer",c); return "myView"; } 

这对我有用,如果你有问题可以添加到你的app-servlet.xml

这个bean,但我认为你不必添加它。

   /WEB-INF/views/   .jsp   

我从mkyong.com得到了答案

使用浏览器访问控制器将发送典型的浏览器Accept标头。 它将不匹配任何视图解析器并默认为第一个(application / xml)或匹配,因为application / xml在Accept列表中。

我建议您使用RestClient http://code.google.com/p/rest-client/来完全控制要发送的Accept标头(如果有的话)。

我不建议使用text / xml,因为默认字符集是US-ASCII而不是UTF-8。 这可能会在未来产生时髦的编码问题。 您始终可以指定编码,但appliation / xml具有UTF-8默认编码。