Spring启动控制器内容协商

我有一个在Spring-boot应用程序中编写的简单REST控制器,但我不确定如何实现内容协商以使其根据请求标头中的Content-Type参数返回JSON或XML。 有人可以向我解释一下,我做错了什么?

控制器方法:

@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) public Message getMessageXML(@RequestParam("text") String text) throws Exception { Message message = new Message(); message.setDate(new Date()); message.setName("Test"); message.setAge(99); message.setMessage(text); return message; } 

调用此方法时,我总是得到JSON(即使我将Content-Type指定为application/xmltext/xml )。

当我实现两个方法,每个方法具有不同的映射和不同的内容类型时,我能够从xml中获取XML,但如果我在单个方法中指定两个mediaTypes(如提供的示例),则它不起作用。

我想要的是调用\message端点并接收

  • 当GET请求的Content-Type设置为application / xml时的XML
  • 当Content-Type是application / json时的JSON

任何帮助表示赞赏。

编辑:我更新了我的控制器以接受所有媒体类型

 @RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }, consumes = MediaType.ALL_VALUE) public Message getMessageXML(@RequestParam("text") String text) throws Exception { Message message = new Message(); message.setDate(new Date()); message.setName("Vladimir"); message.setAge(35); message.setMessage(text); return message; } 

您可以在第6点的博客文章@RequestMapping with Produces and Consumes中找到一些提示。

请注意有关Content-Type和Accept标头的部分:

使用Produces和Consumes进行@RequestMapping:我们可以使用标题Content-Type和Accept来查找请求内容以及它想要响应的mime消息。 为清楚起见,@ RequestMapping提供了生成和使用变量,我们可以在其中指定将调用哪个方法的请求内容类型以及响应内容类型。 例如:

 @RequestMapping(value="/method6", produces={"application/json","application/xml"}, consumes="text/html") @ResponseBody public String method6(){ return "method6"; } 

上面的方法只能使用Content-Type作为text / html消息,并且能够生成application / json和application / xml类型的消息。

您还可以尝试这种不同的方法(使用ResponseEntity对象),它允许您找出传入的消息类型并生成相应的消息(同时展开@ResponseBody注释)

您可以使用ContentNegotiationConfigurer

首先,您应该覆盖配置类中的configureContentNegotiation方法:

 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorPathExtension(false). favorParameter(true). defaultContentType(MediaType.APPLICATION_JSON). mediaType("xml", MediaType.APPLICATION_XML); } } 

favorParameter(true) – 支持在参数或接受头上使用路径表达式。

defaultContentType(MediaType.APPLICATION_JSON) – 设置默认内容类型。 这意味着如果你没有传递路径表达式,那么Spring将生成JSON作为响应。

mediaType("xml", MediaType.APPLICATION_XML) – 设置XML的路径表达式键。

现在,如果你声明你的控制器:

 @Controller class AccountController { @RequestMapping(value="/accounts", method=RequestMethod.GET) @ResponseStatus(HttpStatus.OK) public @ResponseBody List list(Model model, Principal principal) { return accountManager.getAccounts(principal) ); } } 

并将其称为localhost:8080/app/accounts.json ,然后Spring将生成JSON作为响应。 因此,如果您调用localhost:8080/app/accounts.xml您将收到XML响应

你可以在这里找到更多相关信息。