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
。
我写了一篇关于它的博客文章:
我有同样的问题。 我假设您使用的是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默认编码。