Java 如何在Spring Boot中将缓存控制头添加到静态资源?
如何在Spring Boot中为静态资源添加Java 如何在Spring Boot中将缓存控制头添加到静态资源?,java,spring-boot,cache-control,Java,Spring Boot,Cache Control,如何在Spring Boot中为静态资源添加缓存控制HTTP头 尝试在应用程序中使用筛选器组件,该组件可以正确写入标头,但缓存控制标头会被覆盖 @组件 公共类CacheBastingFilter实现过滤器{ @凌驾 public void init(FilterConfig FilterConfig)抛出ServletException{ } @凌驾 公共无效doFilter(ServletRequest-req、ServletResponse-resp、FilterChain链) 抛出IOEx
缓存控制HTTP头
尝试在应用程序中使用筛选器组件,该组件可以正确写入标头,但缓存控制
标头会被覆盖
@组件
公共类CacheBastingFilter实现过滤器{
@凌驾
public void init(FilterConfig FilterConfig)抛出ServletException{
}
@凌驾
公共无效doFilter(ServletRequest-req、ServletResponse-resp、FilterChain链)
抛出IOException、ServletException{
HttpServletResponse httpResp=(HttpServletResponse)resp;
httpResp.setHeader(“缓存控制”,“无缓存,无存储,必须重新验证”);
httpResp.setHeader(“此头已设置”,“无缓存,无存储,必须重新验证”);
httpResp.setHeader(“到期”、“0”);
链式过滤器(req,resp);
}
我在浏览器中看到的是:
缓存控制:无存储
已设置此标头:无缓存、无存储,必须重新验证
过期日期:0
我想要的是:
缓存控制:没有缓存,没有存储,必须重新验证
已设置此标头:无缓存、无存储,必须重新验证
过期日期:0
根据ResourceHandlerRegistry
的,这很简单。(我现在没有相关的代码。)
在配置静态资源的地方,只要添加addResourceHandler
方法,它就会返回ResourceHandlerRegistration
对象
在那个里你们可以使用这个方法,你们需要做的是配置和设置一个obejct
这是从spring 4.2开始的,否则您必须按照下面的方式执行
@Configuration
@EnableWebMvc
@ComponentScan("my.packages.here")
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").setCachePeriod(0);
}
}
这是因为Spring安全性:它重写所有缓存头以完全禁用缓存。
因此,我们需要做两件事:
禁用静态资源的spring安全性
启用静态资源缓存处理
在当前版本的Spring Boot中,我们可以在application.properties配置中更改此行为
禁用某些资源的spring安全性:
# Comma-separated list of paths to exclude from the default secured
security.ignored=/myAssets/**
# 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/
spring.resources.cache.cachecontrol.max-age: 3600
启用发送静态资源的缓存标头:
# Comma-separated list of paths to exclude from the default secured
security.ignored=/myAssets/**
# 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/
spring.resources.cache.cachecontrol.max-age: 3600
仅此而已。现在Spring将检查您的静态文件是否已更改,并可以发送更智能的响应(如果自和其他文件被修改)和重写您的应用缓存
此外,如果有理由不为某些资源使用基于内容的版本,您可以使用备用的FixedVersion策略,并在配置中显式设置版本:
#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=
Malenc的回答是正确的。但是,这个实现存在一个问题
下面的代码将在第一个请求上提供正确的缓存控制头,但返回304(未修改)的未来请求不会返回spring security设置的默认缓存控制头。
{code}
我已经向spring团队提出了这个问题,请参阅。这里有这样的回应:“现在确实不应该为整个应用程序禁用安全缓存控制头;禁用特定路径的安全缓存控制头的正确方法(这里是资源处理)在该问题的评论中有解释,请参阅使用spring boot 1.3.3的,我有一个使用Malenc的404答案。
我可以通过添加资源位置来更正它:
@Configuration
public class HttpClientConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS))
.addResourceLocations("/");
}
}
这些属性控制资源的默认缓存标头:
# Comma-separated list of paths to exclude from the default secured
security.ignored=/myAssets/**
# 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/
spring.resources.cache.cachecontrol.max-age: 3600
在spring boot中有很多方法可以缓存http资源。使用spring boot 2.1.1和spring security 5.1.1
1.对于在代码中使用resourcehandler的资源(未测试):
您可以通过这种方式添加自定义的资源扩展
registry.addResourceHandler
用于添加获取资源的uri路径
.addResourceLocations
用于在文件系统中设置资源所在的位置(
给定的是类路径的相对路径,但也可以是文件为://的绝对路径。)
用于设置缓存头(不言自明)
Resourcechain和resolver是可选的(在本例中与默认值完全相同)
2.对于使用应用程序属性配置文件的资源
与上面相同,减去特定的模式,但现在为config。
此配置应用于列出的静态位置中的所有资源。
spring.resources.cache.cachecontrol.no-store=true
spring.resources.cache.cachecontrol.must-revalidate=true
spring.resources.cache.cachecontrol.no-cache=true
3.在控制器级别
这里的Response是作为参数注入控制器方法中的HttpServletResponse
response.setHeader(HttpHeaders.CACHE_CONTROL,
"no-cache, must-revalidate, no-store");
response.setHeader("Expires", "0");
我们还可以在拦截器中添加缓存控制头:
@Override
public void addInterceptors(InterceptorRegistry registry) {
WebContentInterceptor interceptor = new WebContentInterceptor();
interceptor.addCacheMapping(CacheControl.maxAge(60, TimeUnit.SECONDS)
.noTransform()
.mustRevalidate(), "/static/**");
registry.addInterceptor(interceptor);
}
这样我们就不必指定资源位置
我想对使用@Override public void addResourceHandlers(ResourceHandlerRegistry registry){}
的给定答案添加一些有用的注释,因为我遇到了一些问题。它们可能对其他人也有用
假设使用SpringWebMVC的默认SpringBoot2.4应用程序具有以下目录结构
src/main/resources/
|- static/
|- res/
|- css/
|- js/
|- images/
|- favicon.ico
我们希望为css、js、图像和favicon添加缓存。然后配置如下所示:
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.concurrent.TimeUnit;
@Configuration
public class CacheStaticResourcesConfiguration implements WebMvcConfigurer {
/**
* We provide a custom configuration which resolves URL-Requests to static files in the
* classpath (src/main/resources directory).
*
* This overloads a default configuration retrieved at least partly from
* {@link WebProperties.Resources#getStaticLocations()}.
* @param registry ResourceHandlerRegistry
*/
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
/*
* BE AWARE HERE:
*
* .addResourceHandler(): URL Paths
* .addResourceLocations(): Paths in Classpath to look for file
* root "/" refers to src/main/resources
* For configuration example, see:
* org.springframework.boot.autoconfigure.web.WebProperties.Resources().getStaticLocations()
*
* .addResourceLocations("classpath:/static/")
* =>
* addResourceHandler("/**")
* => GET /res/css/main.css
* => resolved as: "classpath:/static/res/css/main.css"
* BUT
* addResourceHandler("/res/**")
* => GET /res/css/main.css
* (spring only appends the ** to the value from
* addResourceLocations())
* => resolved as: "classpath:/static/css/main.css"
*/
registry
.addResourceHandler("/favicon.ico")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)
.noTransform()
.mustRevalidate());
registry
.addResourceHandler("/res/**")
// trailing slash is important!
.addResourceLocations("classpath:/static/res/")
.setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)
.noTransform()
.mustRevalidate());
registry
.addResourceHandler("/images/**")
// trailing slash is important!
.addResourceLocations("classpath:/static/images/")
.setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)
.noTransform()
.mustRevalidate());
}
}
也尝试过了,但没有成功。它添加了X头和各种内容。但是缓存控制总是“无存储”。使用setCacheControl()设置CacheControl对象使服务器发送正确的标题,并通过curl-I
验证。我找不到CacheControl对象和setCacheControl的任何代码示例,请您分享一下您是如何做到这一点的。谢谢!实际上,您不应该使用@EnableWebMvc。这让我花了很多时间来弄清楚发生了什么,因为有些页面没有提供。看看您是否需要重新使用Spring引导时,只需使用Spring.resources.cache period
,并确保将Spring安全性配置为忽略静态资源“当前版本”“关于spring boot?不,它不需要关闭spring安全性。请参阅乐于知道spring boot在对包括index.html在内的静态资源起作用几年后修复此问题。当请求index.html时,我如何防止服务器设置标头(bu