web-dev-qa-db-ja.com

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. setCacheSeconds(-1)を呼び出したWebContentInterceptorを返す_@Bean_を定義します。
  4. プロパティ_spring.resources.cache-period_を-1または_application.properties_の正の値に設定します。

上記のどれも効果がありませんでした。 Spring Bootですべてまたは個々のリクエストに対してこれらのヘッダーを無効または変更するにはどうすればよいですか?

44

キャッシュなしの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/**");
}

これには、キャッシュ制御ヘッダーを正しく取得するために2つのリソースハンドラーを構成する必要があります。

@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リソースの提供 も参照してください。

50

Httpキャッシングのスプリングブートには多くの方法があります。スプリングブート2.1.1を使用し、さらにスプリングセキュリティ5.1.1を使用します。

1。コードでresourcehandlerを使用するリソースの場合:

この方法で、リソースのカスタマイズされた拡張を追加できます。

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/

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

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

no-cache, must-revalidate, private

getHeaderValueは、キャッシュオプションを文字列として出力します。例えば.

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

このSpring拡張機能を見つけました: https://github.com/foo4u/spring-mvc-cache-control

3つのステップを実行するだけです。

ステップ1(pom.xml):

<dependency>
    <groupId>net.rossillo.mvc.cache</groupId>
    <artifactId>spring-mvc-cache-control</artifactId>
    <version>1.1.1-RELEASE</version>
    <scope>compile</scope>
</dependency>

ステップ2(WebMvcConfiguration.Java):

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CacheControlHandlerInterceptor());
    }
}

ステップ3(コントローラー):

@Controller
public class MyRestController {

    @CacheControl(maxAge=31556926)
    @RequestMapping(value = "/someUrl", method = RequestMethod.GET)
    public @ResponseBody ResponseEntity<String> myMethod(
            HttpServletResponse httpResponse) throws SQLException {
        return new ResponseEntity<String>("{}", HttpStatus.OK);
    }
}
5
dap.tci
@Configuration
@EnableAutoConfiguration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/resources/")
                .setCachePeriod(31556926);

    }
}
1
Vazgen Torosyan

静的リソースを認証する必要がない場合は、次のようにします。

import static org.springframework.boot.autoconfigure.security.servlet.PathRequest.toStaticResources;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity
                .ignoring()
                .requestMatchers(toStaticResources().atCommonLocations());
    }
...
}

そしてあなたのapplication.properties

spring.resources.cache.cachecontrol.max-age=43200

設定可能なその他のプロパティについては、 ResourceProperties.Java を参照してください。

0
cstroe

同様の問題が発生しました。いくつかの動的リソース(画像)をブラウザーにキャッシュしたかったのです。画像が変更される場合(あまり頻繁ではありません)、uriの部分を変更します...これは私のソリューションです

    http.headers().cacheControl().disable();
    http.headers().addHeaderWriter(new HeaderWriter() {

        CacheControlHeadersWriter originalWriter = new CacheControlHeadersWriter();

        @Override
        public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
            Collection<String> headerNames = response.getHeaderNames();
            String requestUri = request.getRequestURI();
            if(!requestUri.startsWith("/web/eventImage")) {
                originalWriter.writeHeaders(request, response);
            } else {
               //write header here or do nothing if it was set in the code
            }       
        }
    });
0
Michal Ambrož

コントローラーで以下の行を使用しました。

ResponseEntity.ok().cacheControl(CacheControl.maxAge(secondWeWantTobeCached, TimeUnit.SECONDS)).body(objToReturnInResponse);

応答には、値secondWeWantTobeCachedのヘッダーCache-Controlがあることに注意してください。ただし、アドレスバーにurlと入力してEnterを押すと、リクエストは常にChromeからサーバーに送信されます。ただし、何らかのリンクからurlをヒットすると、ブラウザーは新しいリクエストを送信せず、キャッシュから取得されます。

0
Vikky