在Spring数据REST(通过Spring 1.3.3启动),当我GET的,资源集合比如说people,在@Version不包含在资源属性:
GET
people
@Version
$curl -v http://localhost:8080/api/people/1 * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /api/people/1 HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.42.1 > Accept: */* > < HTTP/1.1 200 OK < Server: Apache-Coyote/1.1 < ETag: "0" < Last-Modified: Tue, 26 Apr 2016 00:08:12 GMT < Content-Type: application/hal+json;charset=UTF-8 < Transfer-Encoding: chunked < Date: Tue, 26 Apr 2016 00:12:56 GMT < { "id" : 1, "createdDate" : { "nano" : 351000000, "epochSecond" : 1461629292 }, "lastModifiedDate" : { "nano" : 351000000, "epochSecond" : 1461629292 }, "firstName" : "Bilbo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "http://localhost:8080/api/people/1" }, "person" : { "href" : "http://localhost:8080/api/people/1" } } * Connection #0 to host localhost left intact
默认情况下,或者在配置Spring Data存储库时:
@Configuration public class ApplicationRepositoryConfiguration extends RepositoryRestMvcConfiguration { @Override protected void configureRepositoryRestConfiguration( RepositoryRestConfiguration config ) { config.exposeIdsFor(Person.class); config.setBasePath("/api/"); } }
该@Version是加的更新,并包含在数据行的版本ETag HTTP头,当我查询特定的资源数据。不必GET在集合中的每个资源上调用a ,我更喜欢@Version在集合中获取,GET这样我可以编写我的应用程序来检查@Version每个资源更新的值,而无需执行n附加GET往返。
有没有一种方法可以将@Version字段包含在每个资源的集合中GET?
实体定义如下所示:
@Data @Entity @EntityListeners(AuditingEntityListener.class) public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @CreatedDate @Column(nullable=false) private Instant createdDate; @LastModifiedDate @Column(nullable=false) private Instant lastModifiedDate; @Version @JsonProperty private Long version; … }
ETag是HTTP等效@Value于后端中表示为属性的内容。Spring Data REST将所有在HTTP协议中具有相应机制的与后端相关的属性完全转换为:ID成为URI(也不应该是有效负载的一部分),@LastModifiedDate属性成为标头,@Version属性,成为ETag。
@Value
@LastModifiedDate
原因很简单:如果使用HTTP,则使用协议手段可用于实现在数据访问级别上实现的功能。这是Spring Data REST 不仅将数据库公开到Web而是实际上检查模型并将模型特征转换为协议特定手段的一个方面。
长话短说:使用Spring Data REST,你有两个更新选项:
PUT
If-Match
409 Conflict
PUT带有If-Match标头-Spring Data REST根据聚合的version属性的当前值检查提交的ETag并返回412 Precondition Failed,以防万一此时不匹配。在这种情况下,客户端可以查找资源的当前状态并决定如何进行。他们可能只是决定PUT不使用If-Match标头来覆盖服务器上使用的内容。 可以对GET请求进行类似的优化:
Spring Data REST
412 Precondition Failed
GETwith If-None-Match(ETag)/ If-Modified-Since(带有Last-Modified标头值)—如果304 Not Modified资源仍与以前一样,你将看到一个,因此避免了为响应花费带宽。
GETwith If-None-Match(ETag)/ If-Modified-Since
304 Not Modified