Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring Boot中将缓存控制头添加到静态资源?_Java_Spring Boot_Cache Control - Fatal编程技术网

Java 如何在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

如何在Spring Boot中为静态资源添加
缓存控制
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