9.在头文件下有条件的操作
本节将展示 Spring Data REST 如何利用标准的HTTP来完成表现。条件化操作,很容易导致一个更复杂的前端。
9.1.ETag, If-Match, 和 If-None-Match 头文件
ETag header 提供了一个方法来附加资源。这可以防止客户端相互覆盖,同时也使有可能减少不必要的调用
例子3,一个POJO和一个版本号
publicclassSample{@VersionLong version;(1)Sample(Long version){this.version = version;}}
1 | Spring Data普通的 @Version注释标记这个领域作为一个版本标记. |
---|---|
这个POJO,当通过 Spring Data RES被提供为一个REST,将会有一个版本字段的值的ETag
header
我们能有条件的对数据进行PUT
, PATCH
, 或者 DELETE
如果我们提供了一个像这个一样的 If-Match header
curl -v -X PATCH -H 'If-Match:' ...
只有当资源现在的ETag状态和If-Match header
相匹配,这个动作才会被开展。这可以防止客户端操作和其他的操作重合。
不同的客户端可以获取资源,并有一个相同的ETag 。如果一个客户端更新资源,在回复里面将会得到一个新的ETag。
但是第一个客户依然有旧的头文件。如果一个客户端尝试更新If-Match header
,这个更新将会失败因为他们不匹配。
相反,这个客户端将会收到一个被送回来的HTTP412 Precondition Failed
信息。客户端可以赶上进度,尽管这是必须的。
“版本”可以用不同的语义,不同的数据存储区,甚至不同的语义,在您的应用程序。Spring Data REST有效地委托给数据存储的元模型辨别字段是否符合版本如果是,如果ETags相同,只允许列出的更新。 | |
---|---|
If-None-Match header提供了一种可以替代的方案而不是有条件的更新,If-None-Match
允许条件查询。
curl -v -H 'If-None-Match:' ...
这个命令(默认情况下)执行一个GET
,当在执行GET,Spring Data REST将会检查 If-None-Match headers
如果这个头文件和ETag匹配,他将会结束,没有东西改变。而不是发送一个副本资源,是寄回一个HTTP 304 Not Modified
状态代码,从语义上讲,它读作“如果这个提供的头文件不匹配的服务器端的版本,然后发送我的整个资源,否则,不要给我任何东西。
这是一个基于POJO从它的单元测试,所以这个没有@Entity (JPA) 或者 @Document (MongoDB) 注释如预期的应用程序代码。他只是集中在一个领域用 @Version在ETag的头文件 |
|
---|---|
9.2.If-Modified-Since头文件
If-Modified-Since header 提供了一个方法来检查自从最后一个请求更新开始是否资源一直以来避免重新发送相同的数据。 例4 域类型中捕获的最后一个修改日期
Unresolved directive in etags-and-other-conditionals.adoc - include::../../../spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/Receipt.java[tag=code]
1 | Spring Data Commons的@LastModifiedDate 注释允许以多种形式捕获这些信息。(JodaTime’s DateTime , legacy Java Date and Calendar , JDK8 date/time types, 以及 long /Long ). |
---|---|
在这个域下 Spring Data REST将会返回一个Last-Modified
头文件如下:
Last-Modified: Wed, 24 Jun 2015 20:28:15 GMT
此值可以被捕获,并用于后续的查询,如果它没有被更新,可以避免两次获取相同的数据。
curl -H "If-Modified-Since: Wed, 24 Jun 2015 20:28:15 GMT" ...
有了这个简单的命令,如果从那个时候被改变了你要求的资源只会被拿来。 如果是这样的话,你会得到一个修正的 Last-Modified头文件来更新客户端,如果不是你将会收到一个 HTTP 304 Not Modified状态代码
标题是完全格式化的,以发送回一个未来的查询 | |不要混合和匹配不同查询的标题值。结果可能是灾难性的。只有当你请求相同的URI和参数,才使用头文件的值.| | --- | --- |
9.3.构建一个高效的前端
ETags结合 If-Match
和 If-None-Match
头文件授权你去建立前端,使得消费者的数据计划和手机电池的生活更友好。
- 确定需要锁定的实体并添加一个版本属性。HTML5很好的支持-属性数据,所以把它存储在一个有点像
data-etag
属性的DOM里。 - 确定一个路口将有利于从更新中获益。当获取这些资源,把它存储到DOM里面的
Last-Modified
(也许是data-last-modified
) - 当获取资源,并且嵌入自我的URI到您的DOM节点(也许是
data-uri
或者data-self
),所以也很容易返回资源 - 调整
PUT
/PATCH
/DELETE
操作来用If-Match
而且也处理HTTP412 Precondition Failed
状态代码。 - 调整GET操作来用
If-None-Match
,If-Modified-Since
,并处理 HTTP304 Not Modified
状态代码.
通过嵌入ETags
和Last-Modified
值进入你的DOM(对于本机移动app也可能是在其他地方)你可以减少消费的数据/电池通过没有一遍又一遍检索同样的事情。你也可以避免和其他客户的碰撞,相反,这是提醒你需要调节差异.
因此,在你的前端和一些实体编辑上只要有一点小的调整,后台将提供一些你可以利用在构建对客户端的敏感的细节。