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

Как добавить заголовок 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
4b9b3361

Ответ 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("/");
    }
}

Ответ 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");