java spring-boot cache-control

java - ¿Cómo agregar el encabezado Cache-Control a un recurso estático en Spring Boot?



spring-boot (6)

¿Cómo puedo agregar Cache-Control encabezado HTTP de Cache-Control en Spring Boot para recursos estáticos?

Se intentó usar un componente de filtro en la aplicación, que escribe los encabezados correctamente, pero Cache-Control encabezado Cache-Control se sobrescribe.

@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); }

Lo que obtengo en el navegador es:

Cache-Control:no-store This-Header-Is-Set:no-cache, no-store, must-revalidate Expires:0

Lo que me gustaría es:

Cache-Control:no-cache, no-store, must-revalidate This-Header-Is-Set:no-cache, no-store, must-revalidate Expires:0


Esto sucede debido a Spring Security: reescribe todos los encabezados de caché para deshabilitar el almacenamiento en caché por completo. Así que tenemos que hacer dos cosas:

  1. Desactivar la seguridad de primavera para recursos estáticos
  2. Habilitar el procesamiento de caché de recursos estáticos

En la versión actual de Spring Boot podemos cambiar este comportamiento en la configuración de application.properties.

Deshabilite la seguridad de primavera para algunos recursos:

# Comma-separated list of paths to exclude from the default secured security.ignored=/myAssets/**

Habilitar el envío de encabezados de caché para recursos estáticos

# 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/

Eso es todo. Ahora Spring verificará si sus archivos estáticos se modificaron y puede enviar respuestas más inteligentes (If-Modiffied-Since y otros) y también volverá a escribir su appcache.

Además, si existen razones para no usar la versión basada en contenido para algunos recursos, puede usar la estrategia FixedVersion alternativa y establecer la versión explícitamente en su configuración:

#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=

Ver más en documentos


Hay muchas formas en Spring Boot para almacenar recursos http en caché. Utilizando la bota de resorte 2.1.1 y adicionalmente la seguridad de resorte 5.1.1.

1. Para recursos que utilizan resourcehandler en el código (UNTESTED):

Puede agregar extensiones personalizadas de recursos de esta manera.

registry.addResourceHandler

Es para agregar la ruta uri donde obtener el recurso.

.addResourceLocations

Es para configurar la ubicación en el sistema de archivos donde se ubican los recursos (dado que es un pariente con classpath pero también es posible la ruta absoluta con file :: //).

.setCacheControl

Es para configurar los encabezados de caché (auto explicativo).

La resolución de recursos y la resolución son opcionales (en este caso, exactamente como los valores predeterminados).

@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. Para recursos usando el archivo de configuración de propiedades de la aplicación.

Igual que el anterior, menos los patrones específicos, pero ahora como config. Esta configuración se aplica a todos los recursos en las ubicaciones estáticas enumeradas.

spring.resources.cache.cachecontrol.no-store=true spring.resources.cache.cachecontrol.must-revalidate=true spring.resources.cache.cachecontrol.no-cache=true

3. A nivel de controlador

La respuesta aquí es el HttpServletResponse inyectado en el método del controlador como parámetro.

response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, must-revalidate, no-store"); response.setHeader("Expires", "0");


La respuesta de Maleenc es correcta. Sin embargo, hay un problema con esta implementación.

El siguiente código proporcionará el encabezado de control de caché correcto en la primera solicitud, pero no una solicitud futura que devuelva 304 (Sin modificar) devolverá el encabezado de control de caché predeterminado establecido por la seguridad Spring. {código}

public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").setCacheControl(CacheControl.maxAge(10, TimeUnit.SECONDS)); }

He planteado este problema al equipo de primavera, consulte https://jira.spring.io/browse/SPR-15133 . Aquí estaba la respuesta: "Ahora no debe deshabilitar los encabezados de control de caché de seguridad para toda la aplicación; la forma correcta de deshabilitarlos para una ruta específica (manejo de recursos, aquí) se explica en el comentario del problema, consulte " Solución alternativa " sección."


Según la documentation , de ResourceHandlerRegistry . Es bastante facil (No tengo ningún código relacionado con eso en este momento.)

En el lugar donde configura sus recursos estáticos, simplemente agregue el método addResourceHandler , que devolverá el objeto ResourceHandlerRegistration .

Allí puedes usar el método setCacheControl . Lo que tienes que hacer es configurar y establecer un CacheControl CacheControl.

Esto es desde la primavera 4.2 , de lo contrario tendrá que hacerlo como se muestra a continuación.

@Configuration @EnableWebMvc @ComponentScan("my.packages.here") public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").setCachePeriod(0); } }



Usando spring boot 1.3.3, obtuve una respuesta 404 usando la respuesta maleenc. Podría corregirlo agregando una ubicación de recursos:

@Configuration public class HttpClientConfiguration extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)) .addResourceLocations("/"); } }