返回介绍

16.3.2 在响应中设置头部信息

发布于 2024-08-17 00:45:49 字数 2477 浏览 0 评论 0 收藏 0

在saveSpittle()方法中,我们在处理POST请求的过程中创建了一个新的Spittle资源。但是,按照目前的写法(参考程序清单16.3),我们无法准确地与客户端交流。

在saveSpittle()处理完请求之后,服务器在响应体中包含了Spittle的表述以及HTTP状态码200(OK),将其返回给客户端。这里没有什么大问题,但是还不是完全准确。

当然,假设处理请求的过程中成功创建了资源,状态可以视为OK。但是,我们不仅仅需要说“OK”。我们创建了新的内容,HTTP状态码也将这种情况告诉给了客户端。不过,HTTP 201不仅能够表明请求成功完成,而且还能描述创建了新资源。如果我们希望完整准确地与客户端交流,那么响应是不是应该为201(Created),而不仅仅是200(OK)呢?

根据我们目前所学到的知识,这个问题解决起来很容易。我们需要做的就是为saveSpittle()方法添加@ResponseStatus注解,如下所示:

这应该能够完成我们的任务,现在状态码能够精确反应发生了什么情况。它告诉客户端我们新创建了资源。问题已经得以解决!

但这只是问题的一部分。客户端知道新创建了资源,你觉得客户端会不会感兴趣新创建的资源在哪里呢?毕竟,这是一个新创建的资源,会有一个新的URL与之关联。难道客户端只能猜测新创建资源的URL是什么吗?我们能不能以某种方式将其告诉客户端?

当创建新资源的时候,将资源的URL放在响应的Location头部信息中,并返回给客户端是一种很好的方式。因此,我们需要有一种方式来填充响应头部信息,此时我们的老朋友ResponseEntity就能提供帮助了。

如下的程序清单展现了一个新版本的saveSpittle(),它会返回ResponseEntity用来告诉客户端新创建的资源。

程序清单16.4 当返回ResponseEntity时,在响应中设置头部信息

在这个新的版本中,我们创建了一个HttpHeaders实例,用来存放希望在响应中包含的头部信息值。HttpHeaders是MultiValueMap<String, String>的特殊实现,它有一些便利的Setter方法(如setLocation()),用来设置常见的HTTP头部信息。在得到新创建Spittle资源的URL之后,接下来使用这个头部信息来创建ResponseEntity。

哇!原本简单的saveSpittle()方法瞬间变得臃肿了。但是,更值得关注的是,它使用硬编码值的方式来构建Location头部信息。URL中“localhost”以及“8080”这两个部分尤其需要注意,因为如果我们将应用部署到其他地方,而不是在本地运行的话,它们就不适用了。

我们其实没有必要手动构建URL,Spring提供了UriComponentsBuilder,可以给我们一些帮助。它是一个构建类,通过逐步指定URL中的各种组成部分(如host、端口、路径以及查询),我们能够使用它来构建UriComponents实例。借助UriComponentsBuilder所构建的UriComponents对象,我们就能获得适合设置给Location头部信息的URI。

为了使用UriComponentsBuilder,我们需要做的就是在处理器方法中将其作为一个参数,如下面的程序清单所示。

程序清单16.5 使用UriComponentsBuilder来构建Location URI

在处理器方法所得到的UriComponentsBuilder中,会预先配置已知的信息如host、端口以及Servlet内容。它会从处理器方法所对应的请求中获取这些基础信息。基于这些信息,代码会通过设置路径的方式构建UriComponents其余的部分。

注意,路径的构建分为两步。第一步调用path()方法,将其设置为“/ spittles/”,也就是这个控制器所能处理的基础路径。然后,在第二次调用path()的时候,使用了已保存Spittle的ID。我们可以推断出来,每次调用path()都会基于上次调用的结果。

在路径设置完成之后,调用build()方法来构建UriComponents对象,根据这个对象调用toUri()就能得到新创建Spittle的URI。

在REST API中暴露资源只代表了会话的一端。如果发布的API没有人关心和使用的话,那也没有什么价值。通常来讲,移动或JavaScript应用会是REST API的客户端,但是Spring应用也完全可以使用这些资源。我们换个方向,看一下如何编写Spring代码实现RESTful交互的客户端。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文