【问题标题】:How can I cache a GET response for 5 hours?如何将 GET 响应缓存 5 小时?
【发布时间】:2012-06-27 22:17:44
【问题描述】:

我想要什么

我正在开发一个使用 jersey 映射资源的 maven-jetty-plugin。如何将版本号缓存 5 小时,这样我就不必每次页面加载时都获取它?

我的代码

这是加载后将包含版本号的 html 代码:

...

<footer>
  <hr/>
  VERSION: <span id="version-container">...Loading...</span>
</footer>

这里是 servlet 映射到 'localhost:8080/rest/' 的 web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.container.servlet.ServletContainer
        </servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.resources</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

这是处理 'localhost:8080/rest/version' 的 GET 的 java 代码:

/* ... package & imports omitted ... */

@Path("/")
public class RootResource {

    @GET
    @Path("/version")
    @Produces(MediaType.APPLICATION_JSON)
    public String versionAsJson(){
        return String.format("{ \"version\": \"%s\"}", "v.01");
    }
}

这是页面加载后加载版本的javascript代码(使用jQuery):

$(document).ready(function() {
    $.get("http://localhost:8080/rest/version",
        function(response){
            $("#version-container").html(response.version);
        },
        "json"
    ).error(function(){
        $("#version-container").html("[FAILED TO GET VERSION]");
    });
}

【问题讨论】:

    标签: caching jersey maven-jetty-plugin


    【解决方案1】:

    Guava 库有非常好的缓存支持:

    @Path("/")
    public class Service {
    
      protected LoadingCache<String, String> cache = CacheBuilder.newBuilder()
          .expireAfterWrite(5L, TimeUnit.HOURS).maximumSize(1L)
          .build(new CacheLoader<String, String>() {
            @Override
            public String load(String key) throws Exception {
              return String.format("{ \"version\": \"%s\"}", "v.01");
            }
          });
    
      @GET
      @Path("/version")
      @Produces(MediaType.APPLICATION_JSON)
      public String run() throws ExecutionException {
        return cache.get("version");
      }
    
    }
    

    【讨论】:

    • 刚刚试了一下,它对我来说工作正常。 load 方法中的代码只有在距离上次调用服务超过五个小时后才应该运行。那是您要寻找的行为吗?你能提供更多关于你所看到的细节吗?
    • 我得到了你的解决方案,但我认为它不能解决我的问题。我想缓存响应,这样我就不必每次都调用 GET 了。您的解决方案仍然每次都调用 GET。我觉得解决方案可能需要javascript/html级别的...?
    • 我收到了一些建议(当被告知要查看缓存时)来修改 html 元标记中的“etag”、“cache-control”和“last-modified”。我花了几个小时在谷歌上搜索并尝试我发现的东西,但无济于事。
    • 您是否要完全避免使用网络?您可以将服务调用结果与时间戳一起存储在 local storage 中,然后客户端可以在重新加载期间做出决定是使用存储的值还是向服务发出另一个请求。
    • 在检查了需求之后,我现在意识到我需要在 IE7 上运行这个...那么,您是否碰巧知道一个可以在 IE7 上运行的好方法?
    猜你喜欢
    • 2016-10-11
    • 2017-12-03
    • 2022-01-06
    • 2012-12-16
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    相关资源
    最近更新 更多