【问题标题】:How to prevent Java Web Start application caching additional download resources如何防止 Java Web Start 应用程序缓存额外的下载资源
【发布时间】:2015-12-31 19:06:28
【问题描述】:

我的 JWS 应用程序使用一个库(也是我的代码),它在后台从服务器检索各种 XML 文档:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(xmlFileUrl);

URL 中的内容会不时发生变化,应用程序需要在启动时重新获取内容,然后在运行时重新获取内容。

问题是JWS缓存了内容,并为后续请求返回缓存的内容。

告诉 JWS 删除 URL 的缓存内容确实有效:

DownloadService ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
ds.removeResource(xmlFileUrl, null);

但是该库被其他前端使用,我想避免使该库依赖于javaws.jar。我当前的解决方案在库中定义了一个接口,允许库请求清除缓存。 JWS 启动器将接口的实现传递给库。有多个组件可以获取各种资源,虽然我可以让它工作,但整个事情很笨拙。

另一种解决方法是为每个请求附加一个唯一的查询,例如

url += "?ignored="+System.currentTimeMillis()+Math.random();

但这会污染 JWS 缓存,我将其视为混乱、wtf 和臃肿的根源。

XML 文档是在服务器上生成的。设置标题:

Cache-Control: no-cache'

没有帮助。

如果有针对此问题的 更清洁 解决方案,我很感兴趣。如果我可以在服务器上设置一些 HTTP 标头,那将是理想的。列出不缓存在 .jnlp 中的资源是可以接受的,但并不理想,因为 URL 是在库中构建的,我必须大幅更改初始化代码。欢迎其他方法和想法。

【问题讨论】:

    标签: java caching java-web-start jnlp


    【解决方案1】:

    似乎可行的一件事是将请求方法更改为 POST:

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    
    // open connection manually to set request method to POST
    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
    connection.setRequestMethod("POST");
    
    Document doc = db.parse(connection.getInputStream());
    

    这解决了我当前的任务。 我不确定这是否适用于重新获取,例如图片。

    同样直接从 InputStream 构建 XML 文档可能会错过读取 HTTP 响应标头的机会,因此可能会遇到编码问题。

    【讨论】:

      【解决方案2】:

      我很惊讶我之前没有看到 void java.net.URLConnection.setUseCaches(boolean usecaches) 方法。

      此解决方案适用于 JWS。 它不依赖干净简单的javaws.jar。

      URL url = new URL(xmlFileLocation);
      URLConnection connection = url.openConnection();
      // Prevent JavaWebStart from returning cached copy.
      connection.setUseCaches(false);
      
      // Now fetch the content, e.g.
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      Document doc = db.parse(connection.getInputStream());
      

      这仍然是落后的,因为使用服务器响应的应用程序决定不使用缓存,而不是框架 (JWS) 尊重服务器端缓存控制 HTTP 标头。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-30
        • 2019-07-30
        • 1970-01-01
        相关资源
        最近更新 更多