Cómo habilitar el almacenamiento en caché de respuestas HTTP en Spring Boot

Implementé un servidor REST usando Spring Boot 1.0.2. Tengo problemas para evitar que Spring establezca encabezados HTTP que deshabiliten el almacenamiento en caché de HTTP.

Mi controlador es el siguiente:

@Controller public class MyRestController { @RequestMapping(value = "/someUrl", method = RequestMethod.GET) public @ResponseBody ResponseEntity myMethod( HttpServletResponse httpResponse) throws SQLException { return new ResponseEntity("{}", HttpStatus.OK); } } 

Todas las respuestas HTTP contienen los siguientes encabezados:

 Cache-Control: no-cache, no-store, max-age=0, must-revalidate Expires: 0 Pragma: no-cache 

Intenté lo siguiente para eliminar o cambiar esos encabezados:

  1. Llame a setCacheSeconds(-1) en el controlador.
  2. Llame httpResponse.setHeader("Cache-Control", "max-age=123") en el controlador.
  3. Defina @Bean que devuelve WebContentInterceptor para el que he llamado a setCacheSeconds(-1) .
  4. Establezca la propiedad spring.resources.cache-period en -1 o un valor positivo en application.properties .

Ninguno de los anteriores ha tenido ningún efecto. ¿Cómo desactivo o cambio estos encabezados para todas las solicitudes individuales en Spring Boot?

Resulta que los encabezados HTTP sin caché son establecidos por Spring Security. Esto se trata en http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#headers .

A continuación, se deshabilita el encabezado de respuesta HTTP Pragma: no-cache , pero de lo contrario no resuelve el problema:

 import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; @Configuration @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // Prevent the HTTP response header of "Pragma: no-cache". http.headers().cacheControl().disable(); } } 

Terminé deshabilitando completamente Spring Security para recursos públicos estáticos de la siguiente manera (en la misma clase que la anterior):

 @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/static/public/**"); } 

Esto requiere configurar dos manejadores de recursos para obtener los encabezados de control de caché correctos:

 @Configuration public class MvcConfigurer extends WebMvcConfigurerAdapter implements EmbeddedServletContainerCustomizer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // Resources without Spring Security. No cache control response headers. registry.addResourceHandler("/static/public/**") .addResourceLocations("classpath:/static/public/"); // Resources controlled by Spring Security, which // adds "Cache-Control: must-revalidate". registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/static/") .setCachePeriod(3600*24); } } 

Consulte también Servicio de recursos web estáticos en la aplicación Spring Boot & Spring Security .

Encontré esta extensión de spring: https://github.com/foo4u/spring-mvc-cache-control .

Solo tienes que hacer tres pasos.

Paso 1 (pom.xml):

  net.rossillo.mvc.cache spring-mvc-cache-control 1.1.1-RELEASE compile  

Paso 2 (WebMvcConfiguration.java):

 @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new CacheControlHandlerInterceptor()); } } 

Paso 3 (Controlador):

 @Controller public class MyRestController { @CacheControl(maxAge=31556926) @RequestMapping(value = "/someUrl", method = RequestMethod.GET) public @ResponseBody ResponseEntity myMethod( HttpServletResponse httpResponse) throws SQLException { return new ResponseEntity("{}", HttpStatus.OK); } } 

Spring Security desactiva sus encabezados de almacenamiento en caché. Si tiene algunas respuestas dinámicas que no necesitan ser protegidas y desea usar encabezados http para almacenarlas en caché, simplemente es la ruta a su propiedad application.property:

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

Ver más en documentos

Me encuentro con un problema similar. Quería obtener solo algunos de los recursos dynamics (imágenes) en la memoria caché del navegador. Si la imagen cambia (no muy a menudo) cambio la parte de uri … Esta es mi solución

  http.headers().cacheControl().disable(); http.headers().addHeaderWriter(new HeaderWriter() { CacheControlHeadersWriter originalWriter = new CacheControlHeadersWriter(); @Override public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { Collection headerNames = response.getHeaderNames(); String requestUri = request.getRequestURI(); if(!requestUri.startsWith("/web/eventImage")) { originalWriter.writeHeaders(request, response); } else { //write header here or do nothing if it was set in the code } } }); 
 @Configuration @EnableAutoConfiguration public class WebMvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**") .addResourceLocations("/resources/") .setCachePeriod(31556926); } }