Java 缓存REST方法

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

我试图缓存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> 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))));
}