Предположим, у меня есть следующий вызов веб-службы с использованием метода @GET
:
@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 секунд до получения данных из моей базы данных.
Когда я вызываю свой веб-сервис с помощью Firefox Poster, в течение 60 секунд он казался намного быстрее на 2-м, 3-м звонках и т.д., Пока он не прошел 60 секунд.
Однако, когда я вставляю URI в браузер (Chrome), он, кажется, замедляет 5 секунд каждый раз. И я действительно смущен тем, как на самом деле кеширование выполняется с помощью этой техники. Вот мои вопросы:
- Действительно ли POSTER смотрит заголовок
max-age
и решает, когда получить данные? - На стороне клиента (веб, android....), при доступе к моей веб-службе мне нужно проверить заголовок, а затем выполнять кеширование вручную или браузер уже кэшировал данные сам?
- Есть ли способ избежать сбора данных из базы данных каждый раз? Думаю, мне придется как-то хранить свои данные в памяти, но может ли он иметь ограниченный объем памяти?
-
В этом учебнике Учебное пособие по кешированию JAX-RS: Как работает кеширование? Первая строка всегда извлекает данные из базы данных:
Запишите 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();
}