我正在考虑从Apache CXF RS与JAX RS切换到
Spring MVC REST,并查看Spring MVC REST当前正在处理ETag的方式的一些问题.也许我不明白,还是有更好的方式来实现JAX RS目前正在做的工作?
使用Apache CXF RS,在REST服务中评估最后修改的时间戳和ETag的条件(条件评估实际上相当复杂,请参见RFC 2616第14.24和14.26节,因此我很高兴为我做).代码看起来像这样:
@GET
@Path("...")
@Produces(MediaType.APPLICATION_JSON)
public Response findBy...(...,@Context Request request) {
... result = ...fetch-result-or-parts-of-it...;
final EntityTag eTag = new EntityTag(computeETagValue(result),true);
ResponseBuilder builder = request.evaluatePreconditions(lastModified,eTag);
if (builder == null) {
// a new response is required,because the ETag or time stamp do not match
// ...potentially fetch full result object now,then:
builder = Response.ok(result);
} else {
// a new response is not needed,send "not modified" status without a body
}
final CacheControl cacheControl = new CacheControl();
cacheControl.setPrivate(true); // store in private browser cache of user only
cacheControl.setMaxAge(15); // may stay unchecked in private browser cache for 15s,afterwards revalidation is required
cacheControl.setNoTransform(true); // proxies must not transform the response
return builder
.cacheControl(cacheControl)
.lastModified(lastModified)
.tag(eTag)
.build();
}
我尝试与Spring MVC REST相同的事情看起来像这样:
@RequestMapping(value="...",produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<...> findByGpnPrefixCacheable(...) {
... result = ...fetch-result...;
// ... result = ...fetch-result-or-parts-of-it...; - can't fetch parts,must obtain full result,see below
final String eTag = "W/\""+computeETagValue(result)+"\""; // need to manually construct,as opposed to convenient JAX RS above
return ResponseEntity
.ok() // always say 'ok' (200)?
.cacheControl(
CacheControl
.cachePrivate()
.maxAge(15,TimeUnit.SECONDS)
.noTransform()
)
.eTag(eTag)
.body(result); // ETag comparison takes place outside controller(?),but data for a full response has already been built - that is wasteful!
}
即使不需要,我也需要先建立所有的数据以获得完整的响应.这使得在Spring MVC REST中使用的ETag远远不如它可能是有价值的.对我的理解,一个弱的ETag的想法是,建立它的价值可能是“便宜的”,并将其进行比较.在快乐的情况下,这可以防止服务器上的加载.在资源被修改的情况下,当然需要构建完整的响应.
在我看来,通过设计Spring MVC REST目前需要构建完整的响应数据,无论最终是否需要响应的主体.
所以,总结Spring MVC REST的两个问题:
>有等价于evaluatePreconditions()吗?
>是否有更好的方式构建ETag字符串?
谢谢你的想法!