Как на практике работает URLConnection.setUseCaches()?

У меня есть апплет, который загружает изображения через http-соединение, используя URLConnection. Я устанавливаю setUseCaches(true) для всех подключений, но по-прежнему не вижу поведения кеширования. Заголовки HTTP моего изображения имеют разумные настройки кеша. Если вы посмотрите на ошибку 4528599, то увидите довольно загадочное утверждение:

Текущая версия (1.3.1) подключаемого модуля Java проверяет кэш браузера только на наличие файлов, имена которых заканчиваются на .jar или .class. Мне сказали, что для Java Plug-In 1.4 кэш браузера будет проверяться на наличие следующих типов файлов: .class, .jar, .zip, .jpg, .gif, .wav, .au.

Конечно, это было помечено как ИСПРАВЛЕНО для 1.6, но даже в 1.6 я не вижу кэширования. Мои изображения представляют собой файлы PNG, и в некоторых случаях они не имеют расширения .png. Я не вижу кэширования.

В отчете об исправлении ошибок говорится об Unified Download Engine 1.6, но Google, похоже, мало что знает об этом.

Это должно работать, или это просто еще одна сломанная «функция» Sun. Есть ли способ или обходной путь, где я могу заставить свой апплет загружать изображения PNG из кеша браузера? Я бы предпочел не реализовывать свои собственные....

ОБНОВЛЕНИЕ: кэширование, похоже, связано с ResponseCache реализация. Дополнительную информацию о как это работает. Последняя строка говорит:

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

Поэтому мне кажется, что на самом деле возникает вопрос: как на самом деле работает реализация Java Plugin ResponseCache? В чем разница между v1.4/v1.5/v.16

У кого-нибудь есть идеи?


person Joel Carranza    schedule 25.08.2009    source источник


Ответы (2)


Этот метод, скорее всего, только устанавливает директивы заголовка HTTP Cache-Control в исходящем запросе на значения, разрешающие кэширование. Если бы вы вызвали setUseCaches(false), было бы

Cache-Control: no-cache

директива например. Чтобы проверить это, вы можете поместить прокси-сервер отладки HTTP между вашим апплетом и сервером и посмотреть на заголовки.

Теперь только потому, что в запросе говорится, что он готов использовать кэши, ваш сервер может быть не настроен для их включения. Возможно, он не устанавливает заголовок Expires с соответствующим длительным временем в ответе или, возможно, устанавливает заголовок Cache-Control в ответе, который запрещает кэширование.

Некоторые другие вещи, чтобы проверить:

  • ответы https никогда не кэшируются;
  • У вас может не быть кэша HTTP между клиентом и сервером;
  • Единственный HTTP-кэш — это кеш браузера, но его можно отключить или настроить так, чтобы он занимал очень мало места на диске.

Если бы это был просто тест ванильного браузера для веб-приложения, вы также хотели бы убедиться, что вы не нажимаете кнопку обновления, поскольку это эквивалентно установке без кэширования.

person Jim Ferrans    schedule 25.08.2009

Абстрактный класс URLConnection предоставляет методы set/getUseCaches, которые могут использоваться любыми подклассами. Однако, насколько мне удалось определить, класс HttpURLConnection никоим образом не использует эти поля. Установка значения true или false не будет иметь никакого другого поведения.

Если вы хотите добавить режим HTTP-кэширования, вы можете сделать это самостоятельно (написать свой собственный или расширить HttpURLConnector или использовать сокеты) или попробовать использовать If-Modified-Since и If-None-Match и найдите код состояния 304 (не изменено). Второй вариант, вероятно, самый простой и даст вам наилучшие результаты.

person joe p    schedule 25.08.2009
comment
Написание собственного нетривиально, когда кеш постоянный. Вам нужно сделать его доступным для нескольких JVM, работающих одновременно, и вам нужно ограничить его размер. Это действительно должно работать.... ааа... - person Joel Carranza; 26.08.2009
comment
Я определенно рекомендую не сворачивать собственный кеш. Если клиент и сервер отправляют правильные заголовки HTTP, но между клиентом и сервером не настроен промежуточный кэш HTTP, установите прокси-кэш, такой как Varnish, Pound или Squid. - person Jim Ferrans; 26.08.2009