我正在使用 spring-boot 并希望阻止缓存 index.html 但缓存所有其他资源,我已将资源文件放在我的类路径上并使用以下内容阻止缓存。
目前我正在执行以下操作,即缓存所有文件。
@Configuration
public class StaticResourceConfig extends WebMvcConfigurerAdapter {
private static final int SEVEN_DAYS_IN_SECONDS = 604800;
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:frontend/dist/")
.setCachePeriod(SEVEN_DAYS_IN_SECONDS);
super.addResourceHandlers(registry);
}
}
index.html 文件位于 frontend/dist/index.html
我设法这样做了:
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/index.html")
.addResourceLocations("classpath:frontend/dist/index.html")
.setCachePeriod(0);
registry.addResourceHandler("/assets/**")
.addResourceLocations("classpath:frontend/dist/assets")
.setCachePeriod(SEVEN_DAYS_IN_SECONDS);
super.addResourceHandlers(registry);
}
使用 Spring Boot 2.1.1 以及 Spring Security 5.1.1。
1。对于在代码中使用资源处理程序的资源(未经测试):
您可以通过这种方式添加自定义的资源扩展。
registry.addResourceHandler
用于添加获取资源的uri路径
.addResourceLocations
用于设置资源在文件系统中的位置( 给出的是类路径的亲戚
.setCacheControl
.setCachePeriod
用于设置缓存标头(不言自明。)
资源链和解析器是可选的(在本例中与默认值完全相同。)
@Configuration
public class CustomWebMVCConfig implements WebMvcConfigurer {
private static final int SEVEN_DAYS_IN_SECONDS = 604800;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
registry.setOrder(1).addResourceHandler("/index.html")
.addResourceLocations("classpath:frontend/dist/")
.setCacheControl(CacheControl.maxAge(0, TimeUnit.SECONDS)
.mustRevalidate())
.setCacheControl(CacheControl.noCache())
.setCacheControl(CacheControl.noStore())
.resourceChain(true)
.addResolver(new PathResourceResolver());
registry.setOrder(0).addResourceHandler("/**")
.addResourceLocations("classpath:frontend/dist/")
.setCachePeriod(SEVEN_DAYS_IN_SECONDS)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
2。在控制器级别
(yourwebsite.com/index.html)
@GetMapping("/index.html")
public void getIndex(HttpServletResponse response) {
response.setHeader(HttpHeaders.CACHE_CONTROL,
"no-cache, no-store, max-age=0, must-revalidate");
}
您可以使用
MappedInterceptor
和 WebContentInterceptor
作为将 Cache-Control
标头配置到不同静态资源的更灵活的解决方案。
@Bean
public MappedInterceptor cacheControlInterceptor() {
WebContentInterceptor webContentInterceptor = new WebContentInterceptor();
webContentInterceptor.setCacheControl(CacheControl.maxAge(0, TimeUnit.SECONDS).cachePublic());
webContentInterceptor.addCacheMapping(CacheControl.noStore().mustRevalidate(), "/index.html");
// if using Spring Security CacheControlHeadersWriter:
// webContentInterceptor.addCacheMapping(CacheControl.empty(), "/", "/index.html");
return new MappedInterceptor(null, webContentInterceptor);
}
为什么需要bean?请参阅注意
另请参阅:SPR-10655和SPR-13780(这可能很奇怪,因为即使 Spring Security CacheControlHeadersWriter 也使用 4 个指令链,例如“no-cache、no-store、max-age=0、must-revalidate” ”)
jax 的解决方案很好,但请注意不要
extend WebMvcConfigurationSupport
否则它不起作用,并且使用 Spring Boot 您可以扩展配置,因此您不需要第二部分。这段代码有效:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class SinglePageApplicationResourceHandler implements WebMvcConfigurer {
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/index.html")
.addResourceLocations("classpath:/public/index.html")
.setCachePeriod(0);
}
}
您通常需要使用如下所示的包罗万象的映射来扩展它:
@Controller
public class SinglePageApplicationController {
@RequestMapping("/**/{path:[^.]*}")
public String redirect() {
return "forward:/index.html";
}
}