Как включить кеширование HTTP для обработчика ресурсов с помощью Spring MVC и Spring Безопасность

Я хочу включить кеширование HTTP для некоторых статических ресурсов, таких как изображения, для которых доступ ограничен Spring Security. (Эти ресурсы не являются критическими для безопасности, но не должны быть общедоступными). Как избежать Spring безопасности добавления заголовков ответов HTTP, которые запрещают кеширование?

Если я добавлю setCachePeriod() в мою регистрацию обработчика ресурсов в WebMvcConfigurerAdapter.addResourceHandlers() следующим образом:

registry.addResourceHandler("/static/**")
  .addResourceLocations("classpath:/static/").setCachePeriod(3600);

Ресурсы по-прежнему возвращаются со следующими заголовками, которые отключают кеширование:

Cache-Control: max-age=3600, must-revalidate
Expires: Mon, 04 Aug 2014 07:45:36 GMT
Pragma: no-cache

Я хочу избежать введения какой-либо конфигурации XML в проект, который в настоящее время использует только аннотацию Java.

Есть ли лучшие решения, чем расширение обработчика ресурса Spring?

Ответ 1

Вы можете использовать ресурс webContentInterceptor, чтобы обеспечить статическое кэширование ресурсов.

<mvc:interceptors>
    <mvc:interceptor>
    <mvc:mapping path="/static/*"/>
        <bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
            <property name="cacheSeconds" value="31556926"/>
            <property name="useExpiresHeader" value="true"/>
            <property name="useCacheControlHeader" value="true"/>
            <property name="useCacheControlNoStore" value="true"/>
        </bean>
   </mvc:interceptor>
</mvc:interceptors>

Использование аннотаций для настройки кэширующих перехватчиков выполняется следующим образом. В вашем классе веб-конфигурации вы можете добавить класс bean для WebContentInterceptor и добавить его в список перехватчиков.

@Bean
public WebContentInterceptor webContentInterceptor() {
    WebContentInterceptor interceptor = new WebContentInterceptor();
    interceptor.setCacheSeconds(31556926);
    interceptor.setUseExpiresHeader(true);;
    interceptor.setUseCacheControlHeader(true);
    interceptor.setUseCacheControlNoStore(true);
    return interceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(webContentInterceptor());
}

Обратитесь к этому сайту, чтобы узнать, как это делается.

Ответ 2

Spring 4 документация имеет это решение: "Если вы действительно хотите кэшировать определенные ответы, ваше приложение может выборочно вызывать HttpServletResponse.setHeader(String,String) для переопределения заголовка, установленного Spring Security ". Это полезно для обеспечения правильной кэширования таких вещей, как CSS, JavaScript и изображения.

Ниже приведен фрагмент фрагмента для конфигурации springmvc,

@EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
        .addResourceHandler("/resources/**")
        .addResourceLocations("/resources/")
        .setCachePeriod(31556926);
  }

// ...
}

Для справки: http://docs.spring.io/spring-security/site/docs/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#headers-cache-control

Ответ 3

Вы уже настроены для кеширования. must-revalidate означает, что после истечения срока действия кэша (3600 секунд) он больше не будет использоваться, поэтому ваши заголовки ответов, я думаю, верны для того, что вы хотите.