Подтвердить что ты не робот

API-интерфейс Java Webstart и URLConnection

Описание API кэширования URLConnection объявляется как последнее предложение:

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

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

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

Фон:

Случай 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

поведение отличается. При первом запуске кода сервер связывается. Все последующие исполнения кода не связаны с какой-либо связью с сервером (прослеживается с использованием wirehark).

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

Я думаю, что подход прозрачного расширения соединения с кешированием хорош и хорош и помогает повысить производительность клиентских приложений. Но поскольку сервер в этом случае не определял заголовок 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.<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-запросов: он использует If-Modified-Since и автоматически пытается использовать кодировку gzip - даже если код клиента не устанавливает этот заголовок. Но когда кэш попал, возвращаемый поток не был gzipped, хотя getContentEncoding возвращает "gzip".

Так как кэширование кажется неактивным в стабильной версии webstart на моей машине, я не могу проверить, есть ли ошибка в коде, и поэтому не стесняйтесь сообщать об ошибке.

4b9b3361

Ответ 1

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

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

[...]

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

Ответ 2

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

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

Ответ 3

Кэш, как представляется, реализуется 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

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