Java Webstart和URLConnection缓存API
URLConnection缓存API的描述表示为最后一句:
Java 2 Standard Edition中没有URLConnection缓存的默认实现。 但是,Java插件和Java WebStart确实提供了一个开箱即用的function。
在哪里可以找到有关Webstart ResponseCache的更多信息?
- Webstart的哪些版本在哪些平台上激活缓存?
- 它在哪些情况下是活跃的? 只有HTTP获取?
- 可以配置吗?
- 源代码是否可用?
背景:
情况1
使用以下(groovy)代码
def url = new URL('http://repo1.maven.org/maven2/') def connection = url.openConnection() def result = connection.inputStream.text
我希望每次执行代码时都会联系服务器。 但是当执行时
Java Web Start 10.9.2.05 JRE-Version verwenden 1.7.0_09-b05 Java HotSpot(TM) Client VM
行为是不同的。 第一次执行代码时,会联系服务器。 代码的所有后续执行都不涉及与服务器的任何通信(使用wireshark跟踪)。
但它变得更加奇怪。 重新启动webstart应用程序后,第一次执行代码时,请求URL为http://repo1.maven.org/maven2/.pack.gz
,结果为404
。 仅请求原始url导致304 NOT MODIFIED
。 所有后续执行都不涉及与服务器的任何通信。
我认为使用缓存function透明地增强urlconnection的方法很好,很好,有助于提高客户端应用程序的性能。 但由于在这种情况下服务器没有定义Expires头,也没有定义缓存控制头,我认为上面的代码应该始终询问服务器而不是默默地忽略我的请求。
案例2
以下代码在使用webstart 10.1.1.255执行时不起作用(这是由java 7的早期测试版安装的,但我不知道这是哪一个)
URL url = new URL("http://repo1.maven.org/maven2/"); URLConnection connection = url.openConnection(); connection.setRequestProperty("Accept-Encoding", "gzip"); connection.connect(); InputStream is = connection.getInputStream(); if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) { is = new GZIPInputStream(is); } is.close();
使用Java Web Start 10.1.1.255从第二次执行开始,我得到了一个
java.io.IOException: Not in GZIP format at java.util.zip.GZIPInputStream.readHeader(Unknown Source) at java.util.zip.GZIPInputStream.(Unknown Source) at java.util.zip.GZIPInputStream.(Unknown Source)
使用Java Web Start 1.6.0_24
和现在的Java Web Start 10.2.1.255
我无法重现该问题。
使用Wireshark,我看到在我收到错误的情况下,http头包含一个If-Modified-Since条目,因此返回码是304.在其他情况下,没有If-Modified-Since。 因此,我认为在webstart的稳定版本中缓存并不活跃 – 尽管上面链接的最后一句话。
看来,测试版的缓存会对http获取请求进行积极的调整:它确实使用了If-Modified-Since并自动尝试使用gzip编码 – 即使客户端代码没有设置此标头。 但是当高速缓存被命中时,返回的流不会被gzip压缩,尽管getContentEncoding
返回“gzip”。
由于缓存在我的机器上的稳定版webstart中似乎没有活动,我无法再validation错误是否在代码中,因此不愿提交错误报告。
到目前为止,我发现的唯一信息是JDK 7中的Java Rich Internet Applications增强function
默认情况下启用缓存:默认情况下,现在启用在Web启动模式下运行的应用程序代码的网络内容缓存。 这允许应用程序改进性能并与applet执行模式保持一致。 为确保使用最新的内容副本,应用程序可以使用URLConnection.setUseCaches(false)或请求标头Cache-Control值no-cache / no-store。
[…]
使用gzip编码处理内容的改进:部署缓存将应用程序内容保持为压缩forms,并按照HTTP标头中的gzip内容编码将其返回到应用程序。 这使得行为在不同的执行模式下更加一致(首次启动与后续启动,启用缓存与禁用缓存)。 有关详细信息,请参阅6575586 。
我修改了你的代码。 希望对你有效。
URL url = new URL("http://repo1.maven.org/maven2/"); URLConnection connection = url.openConnection(); connection.setRequestProperty("Accept-Encoding", "ISO-8859-1"); connection.connect(); InputStream is = connection.getInputStream(); if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) { is = new GZIPInputStream(is); } is.close();
缓存似乎由com.sun.deploy.cache.DeployCacheHandler实现,它位于deploy.jar中。 我找不到任何官方资料库的来源; 这个链接是某种灰色市场的副本。
我一眼就看不到任何迹象表明它在任何特定平台上被禁用(或启用!)。 至少从Java 6开始,这个缓存处理程序已经存在。
它只缓存GET请求。 isResourceCacheable
方法中的注释说明:
// do not cache resource if: // 1. cache disabled // 2. useCaches is set to false and resource is non jar/zip file // 3. connection is not a GET request // 4. cache-control header is set to no-store // 5. lastModified and expiration not set // 6. resource is a partial body resource
我没有看到任何直接配置缓存的方法。
- 使用HttpURLConnection使用JSON数据发出PUT请求不起作用
- “java.lang.IllegalStateException:在建立连接后无法设置请求属性”在Android中出错
- 使用HttpClient模拟HTTP POST的问题
- Google App Engine(Java):URL获取响应过大的问题
- Java – 将OutputStream上传为HTTP文件上载
- validationCXF HttpAsyncClient使用use.async.http.conduit上下文属性
- 我可以全局设置HTTP连接的超时吗?
- 用于POST请求的HttpURLConnection App Engine Java示例不起作用
- Java – 通过POST方法轻松发送HTTP参数