如何在 Spring Boot 中启用 HTTP 响应缓存

我已经使用Spring Boot 1.0.2实现了REST服务器。我在阻止Spring设置禁用HTTP缓存的HTTP标头时遇到问题。

我的控制器如下:

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

所有 HTTP 响应都包含以下标头:

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

我尝试了以下方法来删除或更改这些标头:

  1. 调用控制器。setCacheSeconds(-1)
  2. 调用控制器。httpResponse.setHeader("Cache-Control", "max-age=123")
  3. 定义我称之为 .@BeanWebContentInterceptorsetCacheSeconds(-1)
  4. 将属性设置为 -1 或 中的正值。spring.resources.cache-periodapplication.properties

以上均未产生任何影响。如何在Spring Boot中禁用或更改所有或单个请求的这些标头?


答案 1

事实证明,无缓存HTTP标头是由Spring Security设置的。这将在 http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#headers 中讨论。

以下内容禁用 HTTP 响应标头 ,但不能以其他方式解决问题:Pragma: no-cache

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

我最终为公共静态资源完全禁用了Spring Security,如下所示(与上面相同的类):

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

这需要配置两个资源处理程序才能正确获取缓存控制标头:

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

另请参阅在Spring Boot和Spring Security应用程序中提供静态Web资源


答案 2

在 spring boot 中有很多方法可以进行 http 缓存。使用弹簧引导 2.1.1 和另外的弹簧安全 5.1.1。

1. 对于在代码中使用资源处理程序的资源:

您可以通过这种方式添加资源的自定义扩展。

registry.addResourceHandler

用于添加 uri 路径以获取资源

.addResourceLocations

用于在文件系统中设置资源所在的位置(给定的是具有类路径的相对路径,但带有 file::// 的绝对路径也是可能的。

.setCacheControl

用于设置缓存标头(不言自明。

资源链和解析器是可选的(在本例中与默认值完全相同)。

@Configuration
public class CustomWebMVCConfig implements WebMvcConfigurer {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/*.js", "/*.css", "/*.ttf", "/*.woff", "/*.woff2", "/*.eot",
            "/*.svg")
            .addResourceLocations("classpath:/static/")
            .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS)
                    .cachePrivate()
                    .mustRevalidate())
            .resourceChain(true)
            .addResolver(new PathResourceResolver());
    }
}

2. 对于使用应用程序属性的资源,配置文件

同上,减去特定模式,但现在作为配置。此配置将应用于列出的静态位置中的所有资源。

spring.resources.cache.cachecontrol.cache-private=true
spring.resources.cache.cachecontrol.must-revalidate=true
spring.resources.cache.cachecontrol.max-age=31536000
spring.resources.static-locations=classpath:/static/

3. 控制器级别

这里的响应是作为参数注入控制器方法中的 HttpServletResponse。

no-cache, must-revalidate, private

getHeaderValue 会将缓存选项输出为字符串。例如:

response.setHeader(HttpHeaders.CACHE_CONTROL,
            CacheControl.noCache()
                    .cachePrivate()
                    .mustRevalidate()
                    .getHeaderValue());

推荐