【发布时间】:2013-07-05 05:44:35
【问题描述】:
假设我有以下使用@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 调用我的 Web 服务时,在 60 秒内,第二次、第三次调用等等似乎要快得多,直到超过 60 秒。
但是,当我将 URI 粘贴到浏览器(Chrome)时,它似乎每次都会减慢 5 秒。而且我真的很困惑如何使用这种技术实际完成缓存。以下是我的问题:
- POSTER 是否真的查看标题
max-age并决定何时 获取数据? - 在客户端(web、android....), 访问我的网络服务时,我需要检查标题,然后 手动执行缓存或浏览器已经缓存了数据 本身?
- 有没有办法避免从数据库中获取数据 每次?我想我必须以某种方式将我的数据存储在内存中, 但它可能会耗尽内存吗?
-
在本教程中 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)。在眼睛上更容易,不需要解码工作;) -
同样,你可以使用
TimeUnit.SECONDS.sleep(5),顺便说一句 -
关于您的问题,您是否分析了到达浏览器的标头?看起来是浏览器的行为不同,我不相信任何 JAX-RS 实现都会为不同的浏览器产生不同的标头,但是...
-
Poster 确实依赖于 Firefox 缓存机制。但是您需要 firebug 网络选项卡来查看您的 GET 请求是否被缓存。
标签: java web-services http jax-rs http-caching