春季 4 @RequestMapping -- 消耗与标头?

2022-09-05 00:16:01

我正在学习如何使用Spring 4构建RESTful Web服务,我不清楚的一件事是@RequestMapping。我见过一些例子,其中一个使用,其他例子使用消耗(或生产)。headers = "Accept=application/xml"= "application/xml"

例如,在我自己的@RestController类中,我有这个函数...

// POST
@RequestMapping(method = RequestMethod.POST, headers = "Accept=application/xml")
public User create(@RequestBody User user) {
    LOG.info("User = " + user.toString());
return userService.create(user);
}

使用与使用消耗甚至使用有什么区别?headers = "Accept=application/xml"= "application/xml"?headers = "content-type=application/xml"

有人可以解释标头和消耗/生产之间的差异,以及何时使用每个标头?


答案 1

简短的答案
在上面的示例中,使用或将以相同的方式响应客户端,即使用XML表示形式向客户端发送响应。headers = "Accept=application/xml"produces = "application/xml"

较长的答案
i. 标头
对于 RESTful Web 服务,客户端(例如您的浏览器)向服务器发送请求(例如 GET、POST 等),服务器将发送回响应。这是一个 HTTP 事务。请求和响应都有HTTP标头字段(“标头”),它们定义HTTP事务的操作参数(我将客户端请求的标头称为“请求标头”,这些标头与服务器响应“响应标头”的标头不同)。

作为浏览器发送到服务器的请求的一部分,有不同的请求标头,一些示例包括 、等,并且每个标头都有自己的功能(请参阅此处的完整标头列表:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields)。AcceptConnectionContent-Length

使用您的代码示例,如果客户端执行POST请求,Spring将检查请求标头,如果它找到值为的标头,它将请求映射到您上面拥有的方法(在您的情况下,服务器将向客户端返回XML响应表示形式)。Acceptapplication/xmlcreate

让我修改您提供的代码中的元素:headers

@RequestMapping(method = RequestMethod.POST, headers = "Connection=keep-alive")
public User create(@RequestBody User user) {
 ...
}

请注意,该元素现在具有值 。如果客户端执行 POST 请求,Spring 将检查请求标头,如果找到值为 的标头,则会将该客户端请求映射到上述方法。headersConnection=keep-aliveConnectionkeep-alivecreate

ii. 生成和使用
如果用于该方法,则意味着仅当客户端的标头匹配时,客户端请求才会映射到该方法。这实质上是客户端说,“嘿,服务器,我更喜欢以XML表示形式接受您的响应,因此请以XML格式将您的响应发送给我”。实际上,服务器也在说,“嘿,客户端,我只能用XML表示形式为你生成响应,所以我会向你发送这种格式”。链接到春季文档参考produces="application/xml"createcreateAcceptapplication/xmlproduces="application/xml"

如果用于该方法,则意味着仅当客户端的标头匹配时,客户端请求才会映射到该方法(请求标头描述客户端请求传入的表示形式)。这实质上是服务器在说,“嘿,客户端,我只能使用XML表示形式的请求,所以将该格式发送给我”。consumes="application/xml"createcreateContent-Typeapplication/xmlContent-Type

摘要
注释中的元素可以采用不同的请求标头(、等),但元素仅与请求标头相关,而元素仅与请求标头相关。headers@RequestMappingAcceptConnectionCache-ControlproducesAcceptconsumesContent-Type


答案 2

正如 HeadersRequestCondition(处理注释属性中提供的值)的 javadoc 所述headers@RequestMapping

传递给标头名称为“Accept”或“Content-Type”的构造函数的表达式将被忽略。有关这些内容,请参阅消耗请求条件生成请求条件

因此,不要在 中使用这些标头。使用 和 的 和 属性。headersproducesconsumesAcceptContent-Type

至于如何使用它们,文档给出了示例:用于消耗用于生产