如何在Spring Rest Controller中动态设置响应内容类型?

时间:2018-05-09 18:33:33

标签: spring rest spring-mvc

我已经实现了一个API,它将根据客户端的请求返回JSON和XML(即请求中的Accept标头)。它按预期工作。

这里的问题是:即使用户发送Accept标头,在某些特殊情况下(即业务逻辑),我们也需要动态发送响应内容类型。 我曾尝试使用HttpHeaders实现它,但它无法正常工作。

@GetMapping
public ResponseEntity<Response> getQueries(){
...............

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    //headers.add("Content-Type", "application/json");  
    return new ResponseEntity<Response>(response, headers, HttpStatus.OK);
}

我将HTTP状态称为200但响应为错误,即

Unexpected '<'

如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

您的问题是关于内容协商,这是一种允许消费者(您的用户代理)和提供商(您的控制者)同意从响应的媒体类型

获取的功能

首先,由APi消费者决定它将接受哪种媒体类型的反应。这是通过将Accept标头设置为所需类型来完成的。因此,在消费者期望响应类型为JSON的情况下,应该使用&#34; application / json&#34;来配置Accept标头。或&#34; application / xml&#34;对于XML(或每个的任何特定变体,例如&#34; application / xhtml + xml&#34;等等)。

在控制器端,您需要使用&#34;产生&#34;来指定支持的响应媒体类型。注释属性。还有兄弟姐妹的消费&#34;指定支持的请求媒体类型的属性。 Sooo ...我们的映射应该如下:

@GetMapping(value="someEndpoint",
        produces={"application/json","application/xml"})
public ResponseEntity<Page<Person>> getPersons(
        @RequestParam(value = "page", required = true) Integer pPage,
        @RequestParam(value = "size", required = true) Integer pSize) 
{
    Page<Person>  result;
    result = personService.getPersons(new PageRequest(pPage, pSize));
    return new ResponseEntity<>(result, HttpStatus.OK);
}

现在有趣的是,您不必为响应格式化而烦恼,因为Spring将能够根据http请求Accept标头的值检测消费者所需的响应媒体类型。

更好的是,使用正确的配置,如果请求中没有Accept标头,则可以设置默认响应mediaType。因此,通过将默认响应内容类型设置为&#34; application / json&#34;,任何没有Accept标头的请求都将在JSON中提供服务,而消费者必须添加一个Accept:&#34; application / xml&# 34;将响应类型设为xml。

有关此主题和配置设置的示例和变体,请参阅此Spring guide

希望这有帮助,

杰克