Java Webstart и API кэширования URLConnection - PullRequest
27 голосов
/ 18 января 2012

Описание API-интерфейса кэширования URLConnection в последнем предложении гласит:

В Java 2 Standard Edition не реализована реализация кэширования URLConnection по умолчанию.Тем не менее, Java Plugin и Java WebStart предоставляют один из готовых.

Где я могу найти больше информации о Webstart ResponseCache?

  • Какие версии Webstart на каких платформах активируют кэширование?
  • В каких случаях он активен?Только HTTP Get?
  • Можно ли его настроить?
  • Доступен ли исходный код?

Фон:

Дело 1

Со следующим (заводным) кодом

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).

Но это становится еще более странным.После перезапуска приложения веб-запуска при первом выполнении кода запрашивается URL http://repo1.maven.org/maven2/.pack.gz, в результате чего 404.Только чем запрашивается исходный URL, в результате 304 NOT MODIFIED.Все последующие исполнения не предполагают какого-либо взаимодействия с сервером.

Я думаю, что подход прозрачного улучшения соединения url с помощью возможностей кэширования хорош и хорош и помогает повысить производительность клиентских приложений.Но так как сервер в этом случае не определил ни заголовок Expires, ни заголовок управления кэшем, я думаю, что приведенный выше код должен всегда запрашивать сервер и не игнорировать мой запрос в молчании.

Случай 2

Следующий код не работает при запуске с веб-запуском 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Начиная с 10.1.1.255, начиная со второго выполнения, я получил

java.io.IOException: Not in GZIP format
    at java.util.zip.GZIPInputStream.readHeader(Unknown Source)
    at java.util.zip.GZIPInputStream.<init>(Unknown Source)
    at java.util.zip.GZIPInputStream.<init>(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 get:использует If-Modified-Since и автоматически пытается использовать кодировку gzip - даже если код клиента не устанавливает этот заголовок.Но при попадании в кэш возвращаемый поток не распаковывается, хотя getContentEncoding возвращает «gzip».

Поскольку в моей стабильной версии webstart на моем компьютере кэширование неактивно, я не могу проверить, есть ли ошибка в коде, и поэтому не решаюсь подать отчет об ошибке.

Ответы [ 3 ]

3 голосов
/ 13 декабря 2012

Единственная информация, которую я нашел на данный момент, находится на Расширения Java Rich Internet Applications в JDK 7

Кэширование включено по умолчанию: Кэширование сетевого содержимого для кода приложения, работающего вРежим веб-запуска теперь включен по умолчанию.Это позволяет приложению повысить производительность и согласованность с режимом выполнения апплета.Чтобы обеспечить использование последней копии содержимого, приложение может использовать URLConnection.setUseCaches (false) или значения Cache-Control заголовка запроса no-cache / no-store.

[...]

Улучшения для обработки содержимого с помощью кодировки gzip: Кэш развертывания будет хранить содержимое приложения в сжатом виде и возвращать его приложению как есть с использованием кодировки содержимого gzip в заголовке HTTP.Это делает поведение более согласованным в разных режимах выполнения (первый запуск по сравнению с последующим запуском, кэш включен или кэш отключен).Подробнее см. 6575586 .

0 голосов
/ 04 октября 2017

Похоже, что кэш реализован 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

Я не вижу способа напрямую настроить кэш.

0 голосов
/ 04 апреля 2012

Я изменил твой код.Надеюсь, это работает для вас.

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();
...