Java 缓存REST方法
我试图缓存REST方法,但服务器总是返回200,并且响应不包括缓存控制头。当缓存正常工作时,服务器应返回304 休息法Java 缓存REST方法,java,angularjs,rest,Java,Angularjs,Rest,我试图缓存REST方法,但服务器总是返回200,并且响应不包括缓存控制头。当缓存正常工作时,服务器应返回304 休息法 @GET @Path("/{id:[0-9][0-9]*}") @Produces("application/json") public Response findById(@PathParam("id") Long id, @Context Request request) { TypedQuery<User> findBy
@GET
@Path("/{id:[0-9][0-9]*}")
@Produces("application/json")
public Response findById(@PathParam("id") Long id, @Context Request request) {
TypedQuery<User> findByIdQuery = em
.createQuery(
"SELECT DISTINCT u FROM Product u WHERE u.id = :entityId ORDER BY u.id",
User.class);
findByIdQuery.setParameter("entityId", id);
User entity;
try {
entity = findByIdQuery.getSingleResult();
} catch (NoResultException nre) {
entity = null;
}
if (entity == null) {
return Response.status(Status.NOT_FOUND).build();
}
CacheControl cc= new CacheControl();
cc.setMaxAge(86400);
EntityTag etag= new EntityTag(Integer.toString(entity.hashCode()));
ResponseBuilder builder=request.evaluatePreconditions(etag);
if(builder==null)
{
builder=Response.ok(entity);
builder.tag(etag);
}
builder.cacheControl(cc);
return builder.build();
}
怎样才能正确地做到这一点?我的一个老例子。
如果没有匹配的-头,请求应在中包含eTag
。
从服务器端缓存的值计算的eTag
将与请求evaluatePreconditions
中的头中的值匹配。
如果两者相等,则生成的生成器中将包含304。
如果不存在标题或标题不匹配,请返回资源并发送eTag
@GET
@Path("{id}")
public Response personFromId(@PathParam("id") final UUID id, @Context Request request) throws NoSuchAlgorithmException {
EntityTag eTag = null;
final Optional<Person> person = fromCache(id);
if (person.isPresent()) {
eTag = eTagFromPerson(person.get());
}
Response response;
ResponseBuilder responseBuilder = null;
if (null != eTag) {
responseBuilder = request.evaluatePreconditions(eTag);
}
if (null != responseBuilder) {
response = responseBuilder.build();
}
else {
response = personResponseFromId(id).tag(eTag).build();
}
return response;
}
或者通过toString()
,hashCode()
第一次点击时,响应中有哪些标题?是否存在缓存控制标头?缓存控制不是apear。没有任何附加的标题-只有服务器、日期、连接类型和内容信息。如果未覆盖实体哈希代码,则同一用户记录的不同实体实例将获得不同的哈希代码。你需要根据对象内容进行比较。我有一个想法,但我不知道如何在我的解决方案中解决这个问题。你必须使用消去法,并将问题分解为你可以解决的具体简单元素。1.尝试创建可以想象的最简单的函数来返回Cache控件头,并确保它能够进入浏览器。2.然后尝试将用户检索逻辑添加到函数中。3.然后确保系统为同一用户的不同实例获取相同的etag。呵呵,我还发现了一个bug:)
@GET
@Path("{id}")
public Response personFromId(@PathParam("id") final UUID id, @Context Request request) throws NoSuchAlgorithmException {
EntityTag eTag = null;
final Optional<Person> person = fromCache(id);
if (person.isPresent()) {
eTag = eTagFromPerson(person.get());
}
Response response;
ResponseBuilder responseBuilder = null;
if (null != eTag) {
responseBuilder = request.evaluatePreconditions(eTag);
}
if (null != responseBuilder) {
response = responseBuilder.build();
}
else {
response = personResponseFromId(id).tag(eTag).build();
}
return response;
}
private EntityTag eTagFromPerson(final Person person) throws NoSuchAlgorithmException {
return new EntityTag(DatatypeConverter.printHexBinary(MessageDigest.getInstance("SHA-256")
.digest(person.toString().getBytes(StandardCharsets.UTF_8))));
}