은 가정하자 나는 @GET
방법을 사용하여 다음과 같은 웹 서비스 호출이 있습니다JAX-RS에서 캐싱은 어떻게 작동합니까?
@GET
@Path(value = "/user/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserCache(@PathParam("id") String id, @Context HttpHeaders headers) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", id);
SqlSession session = ConnectionFactory.getSqlSessionFactory().openSession();
Cre8Mapper mapper = session.getMapper(Cre8Mapper.class);
// slow it down 5 seconds
Thread.sleep(5000);
// get data from database
User user = mapper.getUser(map);
if (user == null) {
return Response.ok().status(Status.NOT_FOUND).build();
} else {
CacheControl cc = new CacheControl();
// save data for 60 seconds
cc.setMaxAge(60);
cc.setPrivate(true);
return Response.ok(gson.toJson(user)).cacheControl(cc).status(Status.OK).build();
}
}
이 실험을, 나는 5 초 내 데이터베이스에서 데이터를 가져 오는 전에 현재의 thread를 느리게.
Firefox Poster을 사용하여 웹 서비스를 호출 할 때 60 초 이내에 두 번째, 세 번째 호출 등에서 60 초가 될 때까지 훨씬 빠르게 보였습니다.
그러나 브라우저 (Chrome)에 URI를 붙여 넣을 때마다 매 5 초가 느린 것처럼 보였습니다. 캐싱이 실제로이 기법으로 어떻게 수행되는지에 대해서는 정말 혼란 스럽습니다. 여기 내 질문은 :
- 이 포스터는 실제로 헤더
max-age
보고 데이터를 가져 시에 결정합니까? 클라이언트 측에서 - (웹, 안드로이드 ...), 내 웹 서비스에 액세스 내가 헤더를 확인해야하고 수동으로 캐싱을 수행하거나 브라우저가 이미 데이터 자체를 캐시합니까?
- 매번 데이터베이스에서 데이터를 가져 오는 것을 피할 수있는 방법이 있습니까? 어떻게 든 내 데이터를 메모리에 저장해야 할 것 같아요. 하지만 잠재적으로 메모리가 부족할 수 있습니까?
이 튜토리얼의 내용 JAX-RS caching tutorial : 캐싱은 실제로 어떻게 작동합니까? 첫 번째 행은 항상 데이터베이스에서 데이터를 가져옵니다.
Book myBook = getBookFromDB (id);
어떻게 캐시 된 것으로 간주됩니까? 코드가 위/아래 순서로 실행되지 않으면.
@Path("/book/{id}")
@GET
public Response getBook(@PathParam("id") long id, @Context Request request) {
Book myBook = getBookFromDB(id);
CacheControl cc = new CacheControl();
cc.setMaxAge(86400);
EntityTag etag = new EntityTag(Integer.toString(myBook.hashCode()));
ResponseBuilder builder = request.evaluatePreconditions(etag);
// cached resource did change -> serve updated content
if (builder == null){
builder = Response.ok(myBook);
builder.tag(etag);
}
builder.cacheControl(cc);
return builder.build();
}
사이드 노트, 질문에 대답하지 않음 : '86400'대신 'TimeUnit.DAYS.toSeconds (1)'를 사용할 수 있습니다. 눈이 훨씬 쉬우 며 디코딩 노력이 필요하지 않습니다.) – fge
@fge : Thanks;) – Chan
마찬가지로 TimeUnit.SECONDS.sleep (5)를 사용할 수 있습니다. – fge