2014-06-11 20 views
33

Ho implementato un server REST utilizzando Spring Boot 1.0.2. Ho difficoltà a impedire a Spring di impostare le intestazioni HTTP che disabilitano il caching HTTP.Come abilitare la cache di risposta HTTP in Spring Boot

mio controller è come segue:

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

Tutte le risposte HTTP contengono le seguenti intestazioni:

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

ho provato quanto segue per rimuovere o modificare tali intestazioni:

  1. Chiamare setCacheSeconds(-1) nel controller.
  2. Chiamare httpResponse.setHeader("Cache-Control", "max-age=123") nel controller.
  3. Definire @Bean che restituisce WebContentInterceptor per il quale ho chiamato setCacheSeconds(-1).
  4. Impostare la proprietà spring.resources.cache-period su -1 o un valore positivo in application.properties.

Nessuno dei precedenti ha avuto alcun effetto. Come disabilitare o modificare queste intestazioni per tutte o singole richieste in Spring Boot?

+1

Non credo Primavera Boot lo fa (non in nessuno dei campioni che ho provato comunque). Forse puoi condividere un progetto minimale che ha queste intestazioni nelle risposte? –

+1

Hai ragione. Il colpevole si rivelò essere Spring Security. –

risposta

38

Elimina le intestazioni HTTP senza cache impostate da Spring Security. Questo è discusso in http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#headers.

Di seguito disabilita l'intestazione della risposta HTTP Pragma: no-cache, ma non fa altro modo risolve il 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(); 
    } 
} 

Ho finito la disabilitazione Primavera di sicurezza completamente per le risorse statiche pubbliche come segue (nella stessa classe come sopra) :

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

Ciò richiede la configurazione di due gestori di risorse per ottenere le intestazioni di controllo della cache di destra:

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

Vedere anche Serving static web resources in Spring Boot & Spring Security application.

+2

Non è necessario disattivare completamente Spring Security se si desidera avere diverse intestazioni Cache-Control per azioni specifiche del controller come descritto in http://stackoverflow.com/a/36459244/759042. – aha

0

Spring Security disattiva le intestazioni di cache. Se si dispone di alcune risposte dinamiche che non hanno bisogno di essere protetto e che si desidera utilizzare intestazioni HTTP di cache di loro - solo il suo percorso al tuo application.property:

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

Tutte in docs

0

Mi imbatto in un problema simile. Volevo ottenere solo alcune delle risorse dinamiche (immagini) memorizzate nella cache del browser. Se i cambiamenti di immagine (non molto spesso) mi cambiano la parte di uri ... Questo è il mio sollution

http.headers().cacheControl().disable(); 
    http.headers().addHeaderWriter(new HeaderWriter() { 

     CacheControlHeadersWriter originalWriter = new CacheControlHeadersWriter(); 

     @Override 
     public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { 
      Collection<String> 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 
      }  
     } 
    }); 
+1

Si noti che il codice può essere abbreviato in: 'http.headers(). CacheControl(). Disable(); . http.headers() addHeaderWriter (nuova DelegatingRequestMatcherHeaderWriter ( nuova NegatedRequestMatcher (nuova AntPathRequestMatcher ("/ web/eventImage")), nuova CacheControlHeadersWriter() )); ' – yankee

2

Ho trovato questa estensione Primavera: https://github.com/foo4u/spring-mvc-cache-control.

Devi solo fare tre passaggi.

Passaggio 1 (pom.xml):

<dependency> 
    <groupId>net.rossillo.mvc.cache</groupId> 
    <artifactId>spring-mvc-cache-control</artifactId> 
    <version>1.1.1-RELEASE</version> 
    <scope>compile</scope> 
</dependency> 

Fase 2 (WebMvcConfiguration.java):

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

Fase 3 (Controller):

@Controller 
public class MyRestController { 

    @CacheControl(maxAge=31556926) 
    @RequestMapping(value = "/someUrl", method = RequestMethod.GET) 
    public @ResponseBody ResponseEntity<String> myMethod(
      HttpServletResponse httpResponse) throws SQLException { 
     return new ResponseEntity<String>("{}", HttpStatus.OK); 
    } 
} 
2
@Configuration 
@EnableAutoConfiguration 
public class WebMvcConfiguration extends WebMvcConfigurerAdapter { 

    @Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 

     registry.addResourceHandler("/resources/**") 
       .addResourceLocations("/resources/") 
       .setCachePeriod(31556926); 

    } 
} 
+2

questo è solo per le risorse statiche. –

Problemi correlati