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
_
これらのヘッダーを削除または変更するために、次のことを試しました。
setCacheSeconds(-1)
を呼び出します。httpResponse.setHeader("Cache-Control", "max-age=123")
を呼び出します。setCacheSeconds(-1)
を呼び出したWebContentInterceptor
を返す_@Bean
_を定義します。spring.resources.cache-period
_を-1または_application.properties
_の正の値に設定します。上記のどれも効果がありませんでした。 Spring Bootですべてまたは個々のリクエストに対してこれらのヘッダーを無効または変更するにはどうすればよいですか?
キャッシュなしの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リソースの提供 も参照してください。
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());
この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);
}
}
@Configuration
@EnableAutoConfiguration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/")
.setCachePeriod(31556926);
}
}
静的リソースを認証する必要がない場合は、次のようにします。
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 を参照してください。
同様の問題が発生しました。いくつかの動的リソース(画像)をブラウザーにキャッシュしたかったのです。画像が変更される場合(あまり頻繁ではありません)、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
}
}
});
コントローラーで以下の行を使用しました。
ResponseEntity.ok().cacheControl(CacheControl.maxAge(secondWeWantTobeCached, TimeUnit.SECONDS)).body(objToReturnInResponse);
応答には、値secondWeWantTobeCachedのヘッダーCache-Controlがあることに注意してください。ただし、アドレスバーにurlと入力してEnterを押すと、リクエストは常にChromeからサーバーに送信されます。ただし、何らかのリンクからurlをヒットすると、ブラウザーは新しいリクエストを送信せず、キャッシュから取得されます。