Как добавить заголовок Cache-Control в статический ресурс в Spring Boot?
Как добавить Cache-Control
HTTP-заголовок в Spring Boot для статических ресурсов?
Пробовал использовать компонент фильтра в приложении, который правильно записывает заголовки, но заголовок Cache-Control
перезаписывается.
@Component
public class CacheBustingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResp = (HttpServletResponse) resp;
httpResp.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
httpResp.setHeader("This-Header-Is-Set", "no-cache, no-store, must-revalidate");
httpResp.setHeader("Expires", "0");
chain.doFilter(req, resp);
}
Что я получаю в браузере:
Cache-Control:no-store
This-Header-Is-Set:no-cache, no-store, must-revalidate
Expires:0
Я бы хотел:
Cache-Control:no-cache, no-store, must-revalidate
This-Header-Is-Set:no-cache, no-store, must-revalidate
Expires:0
Ответы
Ответ 1
В соответствии с документация, ResourceHandlerRegistry
. Это довольно легко. (У меня сейчас нет кода, связанного с этим.)
В том месте, где вы настраиваете свои статические ресурсы, просто добавьте метод addResourceHandler
, он вернет объект ResourceHandlerRegistration
.
Здесь вы можете использовать метод setCacheControl. Что вам нужно сделать, это настроить и установить CacheControl obejct.
Это с spring 4.2, иначе вам нужно будет сделать это, как показано ниже.
@Configuration
@EnableWebMvc
@ComponentScan("my.packages.here")
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").setCachePeriod(0);
}
}
Ответ 2
Это происходит из-за Spring Безопасность: он перезаписывает все заголовки кеша, чтобы полностью отключить кеширование.
Поэтому нам нужно сделать две вещи:
- Отключить Spring безопасность для статических ресурсов
- Включить обработку кеша статических ресурсов
В текущей версии Spring Boot мы можем изменить это поведение в конфигурации application.properties.
Отключить защиту Spring для некоторых ресурсов:
# Comma-separated list of paths to exclude from the default secured
security.ignored=/myAssets/**
Включить отправку заголовков кеша для статических ресурсов:
# Enable HTML5 application cache manifest rewriting.
spring.resources.chain.html-application-cache=true
# Enable the Spring Resource Handling chain. Disabled by default unless at least one strategy has been enabled.
spring.resources.chain.enabled=true
# Enable the content Version Strategy.
spring.resources.chain.strategy.content.enabled=true
# Comma-separated list of patterns to apply to the Version Strategy.
spring.resources.chain.strategy.content.paths=/**
# Locations of static resources.
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
Это все. Теперь Spring проверяет, были ли ваши статические файлы изменены и может отправлять более умные ответы (If-Modiffied-Since и другие) и переписать также ваш appcache.
Кроме того, если есть причины не использовать контентную версию для некоторых ресурсов, вы можете использовать альтернативную стратегию FixedVersion и задавать версию явно в своей конфигурации:
#Enable the fixed Version Strategy.
spring.resources.chain.strategy.fixed.enabled=false
# Comma-separated list of patterns to apply to the Version Strategy.
spring.resources.chain.strategy.fixed.paths=
# Version string to use for the Version Strategy.
spring.resources.chain.strategy.fixed.version=
Подробнее в документах
Ответ 3
Малеэнс, ответ правильный. Однако есть одна проблема с этой реализацией.
Следующий код предоставит правильный заголовок управления кешем для первого запроса, но не будущий запрос, который возвращает 304 (Not-Modified), вернет заголовок управления кешем по умолчанию, установленный защитой spring.
{code}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").setCacheControl(CacheControl.maxAge(10, TimeUnit.SECONDS));
}
Я поднял эту проблему в команде spring, см. https://jira.spring.io/browse/SPR-15133. Здесь был ответ: "Теперь вам не следует отключать заголовки управления кешем безопасности для всего вашего приложения, поэтому в этом выпуске комментария объясняется правильный способ отключить их для определенного пути (обработка ресурсов), см. Раздел " Временное решение".
Ответ 4
Используя spring boot 1.3.3, я получил ответ 404, используя ответ по манускрипту.
Я мог бы исправить это, добавив местоположение ресурса:
@Configuration
public class HttpClientConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS))
.addResourceLocations("/");
}
}
Ответ 5
Свойства, которые управляют заголовками кэша по умолчанию для ресурсов:
spring.resources.cache.cachecontrol.max-age: 3600
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
Ответ 6
В весенней загрузке есть много способов кэширования http ресурса. Использование пружинного башмака 2.1.1 и дополнительно пружинной безопасности 5.1.1.
1. Для ресурсов, использующих обработчик ресурсов в коде (UNTESTED):
Таким способом вы можете добавлять индивидуальные расширения ресурсов.
registry.addResourceHandler
Для добавления пути URI, где получить ресурс
.addResourceLocations
Предназначен для установки местоположения в файловой системе, где расположены ресурсы (данное значение является относительным с classpath, но также возможен абсолютный путь с file :://.)
.setCacheControl
Предназначен для настройки заголовков кэша (не требует пояснений).
Resourcechain и resolver не являются обязательными (в данном случае они соответствуют значениям по умолчанию).
@Configuration
public class CustomWebMVCConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.noStore()
.mustRevalidate())
.setCacheControl(CacheControl.noCache())
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
}
2. Для ресурсов, использующих файл конфигурации свойств приложения
То же самое, что и выше, за исключением конкретных шаблонов, но теперь как config. Эта конфигурация применяется ко всем ресурсам в перечисленных статических местоположениях.
spring.resources.cache.cachecontrol.no-store=true
spring.resources.cache.cachecontrol.must-revalidate=true
spring.resources.cache.cachecontrol.no-cache=true
3. На уровне контроллера
Ответом здесь является HttpServletResponse, введенный в метод контроллера в качестве параметра.
response.setHeader(HttpHeaders.CACHE_CONTROL,
"no-cache, must-revalidate, no-store");
response.setHeader("Expires", "0");