@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秒内,在第二次,第三次呼叫等等时,看起来要快一些,直到60秒.
但是,当我将URI粘贴到浏览器(Chrome)时,它似乎每次都放缓5秒.我真的很困惑,如何使用这种技术实现缓存.这是我的问题:
> POSTER实际上会看到标题最大时间,并决定何时
取数据?
>在客户端(web,android ….),
当访问我的Web服务时,我需要检查标题然后
手动执行缓存或浏览器已缓存数据
本身?
>有没有办法避免从数据库中获取数据
每次?我想我将不得不以内存存储我的数据,
但是它可能会耗尽内存吗?
>在本教程中
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(); }
解决方法
When I call my web service using Firefox Poster,within 60 seconds it
seemed much faster on the 2nd,3rd calls and so forth,until it passed
60 seconds. However,when I paste the URI to a browser (Chrome),it
seemed to slow down 5s everytime.
示例:
@Path("/book") public Response getBook() throws InterruptedException { String book = " Sample Text Book"; TimeUnit.SECONDS.sleep(5); // thanks @fge final CacheControl cacheControl = new CacheControl(); cacheControl.setMaxAge((int) TimeUnit.MINUTES.toSeconds(1)); return Response.ok(book).cacheControl(cacheControl).build(); }
我有一个安静的网络服务运行和网址为此
http://localhost:8780/caching-1.0/api/cache/book - GET
FireFox:
第一次当我访问url,浏览器发送请求到服务器,并用缓存控制头返回.
第二次请求60秒(使用回车):
这个时候firefox没有去服务器得到响应,而是从缓存中加载数据
60秒后第三次请求(使用回车):
这一次firefox要求服务器得到回应.
使用刷新的第四个请求(F5或ctrl F5):
如果我刷新页面(而不是按进入)在60秒以前的请求中,firefox没有从缓存加载数据,而是请求服务器与特殊头在请求
Chrome:
第二个请求在60秒内(使用回车):此时Chrome再次向服务器发送请求,而不是从缓存加载数据,并在请求中添加了header cache-control =“max-age = 0”
聚合结果:
由于chrome响应不同,输入点击,您在Firefox和chrome中看到不同的行为,它与jax-rs或您的http响应无关.总结客户端(firefox / chrome / safari / opera)将在缓存控制中缓存指定时间段的数据,客户端将不会向服务器发出新请求,除非时间到期或直到我们强制刷新.
我希望这澄清你的问题1,2,3.
4.In this tutorial JAX-RS caching tutorial: How does caching actually
work? The first line always fetch the data from the database:Book myBook = getBookFromDB(id);
So how it is considered cached? Unless the code doesn’t execute in
top/down order.
你所提到的例子并不是说最小化数据库调用,而是关于通过网络保存带宽,如果数据没有更新,客户端已经有了数据和检查服务器(重新验证),重新发送实体.