web-dev-qa-db-ja.com

Spring Bootで静的リソースにCache-Controlヘッダーを追加するにはどうすればよいですか?

静的リソースのSpring BootでCache-Control HTTPヘッダーを追加するにはどうすればよいですか?

ヘッダーを正しく書き込むアプリケーションでフィルターコンポーネントを使用してみましたが、Cache-Controlヘッダーは上書きされます。

@Component
public class CacheBustingFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) 
                                              throws IOException, ServletException {

        HttpServletResponse httpResp = (HttpServletResponse) resp;
        httpResp.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        httpResp.setHeader("This-Header-Is-Set", "no-cache, no-store, must-revalidate");
        httpResp.setHeader("Expires", "0");

        chain.doFilter(req, resp);
    }

ブラウザに表示されるものは次のとおりです。

Cache-Control:no-store
This-Header-Is-Set:no-cache, no-store, must-revalidate
Expires:0

私が望むのは:

Cache-Control:no-cache, no-store, must-revalidate
This-Header-Is-Set:no-cache, no-store, must-revalidate
Expires:0
22
MatteKarla

ドキュメント のように、ResourceHandlerRegistryの。とても簡単です。 (現在、それに関連するコードはありません。)

静的リソースを設定する場所にaddResourceHandlerメソッドを追加するだけで、ResourceHandlerRegistrationオブジェクトを返します。

そこで setCacheControl メソッドを使用できます。行う必要があるのは、 CacheControl obejctを構成および設定することです。

これは春4.2以来です。それ以外の場合は以下のようにする必要があります。

@Configuration
@EnableWebMvc
@ComponentScan("my.packages.here")
public class WebConfig extends WebMvcConfigurerAdapter {


   @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").setCachePeriod(0);
    }

}
12

これは、Spring Securityが原因で発生します。すべてのキャッシュヘッダーを書き換えて、キャッシュを完全に無効にします。したがって、次の2つのことを行う必要があります。

  1. 静的リソースのスプリングセキュリティを無効にする
  2. 静的リソースキャッシュ処理を有効にする

Spring Bootの現在のバージョンでは、application.properties configでこの動作を変更できます。

一部のリソースのスプリングセキュリティを無効にします。

# 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は静的ファイルが変更されたかどうかを確認し、よりスマートな応答(If-Modiffied-Sinceなど)を送信し、アプリキャッシュも書き換えることができます。

また、一部のリソースでコンテンツベースのバージョンを使用しない理由がある場合は、代替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= 

ドキュメントの詳細を参照

13

リソースのデフォルトのキャッシュヘッダーを制御するプロパティは次のとおりです。

spring.resources.cache.cachecontrol.max-age: 3600

https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

3
Mateusz Stefek

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("/**")
            .addResourceLocations("classpath:/static/")
            .setCacheControl(CacheControl.noStore()
                    .mustRevalidate())
            .setCacheControl(CacheControl.noCache())
            .resourceChain(true)
            .addResolver(new PathResourceResolver());
    }
}

2。アプリケーションプロパティ設定ファイルを使用するリソースの場合

上記と同じ、特定のパターンを除いて、今は構成として。 この構成は、リストされている静的ロケーションのすべてのリソースに適用されます。

spring.resources.cache.cachecontrol.no-store=true
spring.resources.cache.cachecontrol.must-revalidate=true
spring.resources.cache.cachecontrol.no-cache=true

。コントローラーレベルで

ここでの応答は、コントローラーメソッドにパラメーターとして挿入されたHttpServletResponseです。

response.setHeader(HttpHeaders.CACHE_CONTROL,
            "no-cache, must-revalidate, no-store");
response.setHeader("Expires", "0");
2
Merv

スプリングブート1.3.3を使用して、malenecの回答を使用して404の回答がありました。リソースの場所を追加することで修正できます。

@Configuration
public class HttpClientConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS))
                .addResourceLocations("/");
    }
}
1
Ronan Fauglas

Maleencの答えは正しい。ただし、この実装には1つの問題があります。

次のコードは、最初の要求で正しいcache-controlヘッダーを提供しますが、304(Not-Modified)を返す将来の要求では、スプリングセキュリティによって設定されたデフォルトのcache-controlヘッダーを返しません。 {コード}

public void addResourceHandlers(ResourceHandlerRegistry registry) {         
    registry.addResourceHandler("/resources/**").setCacheControl(CacheControl.maxAge(10, TimeUnit.SECONDS));
}

この問題を春のチームに提起しました。 https://jira.spring.io/browse/SPR-151 を参照してください。 「アプリケーション全体のセキュリティキャッシュ制御ヘッダーを実際に無効にするべきではありません。特定のパス(リソース処理、ここ)のセキュリティキャッシュ制御ヘッダーを無効にする適切な方法は、この問題のコメントで説明されています。 「回避策」セクション。

1
Thomas Jahncke