java – 缓存如何在JAX-RS中工作?

假设我使用@GET方法进行以下Web服务调用
@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();
    }

解决方法

从你的问题我看到你正在混合客户端缓存(http)与服务器端缓存(数据库).我认为这个的根本原因是你在Firefox和chrome中观察到的不同行为,我会尝试清除这个

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.

你所提到的例子并不是说最小化数据库调用,而是关于通过网络保存带宽,如果数据没有更新,客户端已经有了数据和检查服务器(重新验证),重新发送实体.

相关文章

应用场景 C端用户提交工单、工单创建完成之后、会发布一条工...
线程类,设置有一个公共资源 package cn.org.chris.concurre...
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量