下面列出了怎么用org.springframework.http.CacheControl的API类实例代码及写法,或者点击链接到github查看源代码。
@RequestMapping( value="/{iconKey}/icon.svg", method = RequestMethod.GET )
public void getIconData( HttpServletResponse response, @PathVariable String iconKey ) throws WebMessageException,
IOException
{
Optional<Resource> icon = iconService.getIconResource( iconKey );
if ( !icon.isPresent() )
{
throw new WebMessageException( WebMessageUtils.notFound( String.format( "Icon resource not found: '%s", iconKey ) ) );
}
response.setHeader( "Cache-Control", CacheControl.maxAge( TTL, TimeUnit.DAYS ).getHeaderValue() );
response.setContentType( MediaType.SVG_UTF_8.toString() );
StreamUtils.copy( icon.get().getInputStream(), response.getOutputStream() );
}
@RequestMapping( value = "/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE )
public void searchUserGroups( @RequestParam String key, @RequestParam( required = false ) Integer pageSize,
HttpServletResponse response ) throws IOException, WebMessageException
{
if ( key == null )
{
throw new WebMessageException( WebMessageUtils.conflict( "Search key not specified" ) );
}
int max = pageSize != null ? pageSize : Integer.MAX_VALUE;
List<SharingUserGroupAccess> userGroupAccesses = getSharingUserGroups( key, max );
List<SharingUserAccess> userAccesses = getSharingUser( key, max );
Map<String, Object> output = new HashMap<>();
output.put( "userGroups", userGroupAccesses );
output.put( "users", userAccesses );
response.setContentType( MediaType.APPLICATION_JSON_VALUE );
response.setHeader( ContextUtils.HEADER_CACHE_CONTROL, CacheControl.noCache().cachePrivate().getHeaderValue() );
renderService.toJson( response.getOutputStream(), output );
}
public void configureAnalyticsResponse( HttpServletResponse response, String contentType,
CacheStrategy cacheStrategy, String filename, boolean attachment, Date latestEndDate )
{
// Progressive cache will always take priority
if ( RESPECT_SYSTEM_SETTING == cacheStrategy && webCache.isProgressiveCachingEnabled() && latestEndDate != null )
{
// Uses the progressive TTL
final CacheControl cacheControl = webCache.getCacheControlFor( latestEndDate );
configureResponse( response, contentType, filename, attachment, cacheControl );
}
else
{
// Respects the fixed (predefined) settings
configureResponse( response, contentType, cacheStrategy, filename, attachment );
}
}
@Test
public void testGetAnalyticsCacheControlForWhenTimeToLiveIsPositive()
{
// Given
final long positiveTimeToLive = 60;
final Date aDate = new Date();
final CacheControl expectedCacheControl = stubPublicCacheControl ( positiveTimeToLive );
final Cacheability setCacheability = PUBLIC;
// When
when( systemSettingManager.getSystemSetting( CACHEABILITY ) ).thenReturn( setCacheability );
when( analyticsCacheSettings.progressiveExpirationTimeOrDefault( aDate ) ).thenReturn( positiveTimeToLive );
final CacheControl actualCacheControl = webCache.getCacheControlFor( aDate );
// Then
assertThat( actualCacheControl.toString(), is( expectedCacheControl.toString() ) );
}
@Test
public void testGetCacheControlForWhenCacheStrategyIsRespectSystemSetting()
{
// Given
final CacheStrategy theInputCacheStrategy = RESPECT_SYSTEM_SETTING;
final CacheStrategy theCacheStrategySet = CACHE_5_MINUTES;
final CacheControl expectedCacheControl = stubPublicCacheControl( theCacheStrategySet );
// When
when( systemSettingManager.getSystemSetting( CACHEABILITY ) ).thenReturn( PUBLIC );
when( systemSettingManager.getSystemSetting( CACHE_STRATEGY ) ).thenReturn( theCacheStrategySet );
final CacheControl actualCacheControl = webCache.getCacheControlFor( theInputCacheStrategy );
// Then
assertThat( actualCacheControl.toString(), is( expectedCacheControl.toString() ) );
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/index.html")
.addResourceLocations("classpath:/dist/index.html")
.setCacheControl(CacheControl.noCache())
.setCacheControl(CacheControl.noStore())
.resourceChain(true);
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/dist/static/", "classpath:/static/")
.resourceChain(true);
registry.addResourceHandler("/dist/**")
.addResourceLocations("classpath:/dist/")
.resourceChain(true);
registry.addResourceHandler("/favicon.ico")
.addResourceLocations("classpath:/dist/favicon.ico")
.resourceChain(true);
}
@CrossOrigin(origins = "*")
@GetMapping("/getSavedResource")
public ResponseEntity<byte[]> getSavedResource(@RequestParam(value = "path") String path) {
HttpStatus httpStatus = HttpStatus.OK;
byte[] media = new byte[0];
try (InputStream in =
new FileInputStream(Paths.get(URLDecoder.decode(path, "UTF-8")).toString())) {
media = ByteStreams.toByteArray(in);
} catch (IOException e) {
httpStatus = HttpStatus.NOT_FOUND;
logger.warning("Cannot fetch image: " + path);
}
HttpHeaders headers = new HttpHeaders();
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
headers.setContentType(MediaType.IMAGE_JPEG);
return new ResponseEntity<>(media, headers, httpStatus);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
ResourceHandlerRegistration reg = registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
boolean isLive = environment.acceptsProfiles(Profiles.of(Initializer.PROFILE_LIVE));
int cacheMinutes = isLive ? 15 : 0;
reg.setCachePeriod(cacheMinutes * 60);
//
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(isLive ? 10 : 0)).mustRevalidate());
registry.addResourceHandler("/assets/**")
.addResourceLocations("/webjars/alfio-public-frontend/" + frontendVersion + "/alfio-public-frontend/assets/");
}
private final ResponseEntity.BodyBuilder newResponse(final HttpStatus status, final String etag)
{
ResponseEntity.BodyBuilder response = ResponseEntity.status(status)
.eTag(etag)
.cacheControl(CacheControl.maxAge(cacheMaxAgeSec, TimeUnit.SECONDS));
final String adLanguage = getAdLanguage();
if (adLanguage != null && !adLanguage.isEmpty())
{
final String contentLanguage = ADLanguageList.toHttpLanguageTag(adLanguage);
response.header(HttpHeaders.CONTENT_LANGUAGE, contentLanguage);
response.header(HttpHeaders.VARY, HttpHeaders.ACCEPT_LANGUAGE); // advice browser to include ACCEPT_LANGUAGE in their caching key
}
return response;
}
/**
* Set the HTTP Cache-Control header according to the given settings.
* @param response current HTTP response
* @param cacheControl the pre-configured cache control settings
* @since 4.2
*/
protected final void applyCacheControl(HttpServletResponse response, CacheControl cacheControl) {
String ccValue = cacheControl.getHeaderValue();
if (ccValue != null) {
// Set computed HTTP 1.1 Cache-Control header
response.setHeader(HEADER_CACHE_CONTROL, ccValue);
if (response.containsHeader(HEADER_PRAGMA)) {
// Reset HTTP 1.0 Pragma header if present
response.setHeader(HEADER_PRAGMA, "");
}
if (response.containsHeader(HEADER_EXPIRES)) {
// Reset HTTP 1.0 Expires header if present
response.setHeader(HEADER_EXPIRES, "");
}
}
}
@Test
public void testCache() {
startServerWithoutSecurity(CacheController.class);
getWebTestClient()
.get()
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.valueEquals(HttpHeaders.ETAG, "\"test\"")
.expectHeader()
.cacheControl(CacheControl.maxAge(1, TimeUnit.MINUTES))
.expectBody(String.class)
.isEqualTo("test");
getWebTestClient()
.get()
.header(HttpHeaders.IF_NONE_MATCH, "\"test\"")
.exchange()
.expectStatus()
.isNotModified();
}
/**
* Defines and return a CacheControl object with the correct expiration time and
* cacheability based on the internal system settings defined by the user. The
* expiration time is defined through the Enum {@link CacheStrategy}
*
* @param cacheStrategy
*
* @return a CacheControl object configured based on current system settings.
*/
public CacheControl getCacheControlFor( CacheStrategy cacheStrategy )
{
final CacheControl cacheControl;
if ( RESPECT_SYSTEM_SETTING == cacheStrategy )
{
cacheStrategy = (CacheStrategy) systemSettingManager.getSystemSetting( CACHE_STRATEGY );
}
final boolean cacheStrategyHasExpirationTimeSet = cacheStrategy != null && cacheStrategy != NO_CACHE;
if ( cacheStrategyHasExpirationTimeSet )
{
cacheControl = maxAge( cacheStrategy.toSeconds(), SECONDS );
setCacheabilityFor( cacheControl );
}
else
{
cacheControl = noCache();
}
return cacheControl;
}
/**
* 二维码
*/
@RequestMapping(value = "/createQRCode")
@ResponseBody
public ResponseEntity<byte[]> createQRCode(long id, String text, int width, int height, WebRequest request) throws IOException, WriterException {
// 缓存未失效时直接返回
if (request.checkNotModified(id))
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(MediaType.IMAGE_PNG_VALUE))
.cacheControl(CacheControl.maxAge(1, TimeUnit.DAYS))
.eTag(String.valueOf(id))
.body(null);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(MediaType.IMAGE_PNG_VALUE))
.cacheControl(CacheControl.maxAge(1, TimeUnit.DAYS))
.eTag(String.valueOf(id))
.body(shadowSocksSerivceImpl.createQRCodeImage(text, width, height));
}
@Cacheable("sw")
@GetMapping("/sw.js")
public ResponseEntity<String> serviceWorker() {
ClassPathResource classPathResource = new ClassPathResource("src/sw.mjs");
String loaded = null;
try {
loaded = IOUtils.toString(classPathResource.getInputStream(), "UTF-8");
} catch (IOException e) {
log.error("Error loading service worker", e);
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("text/javascript"))
.cacheControl(CacheControl
.maxAge(0, TimeUnit.SECONDS))
.body(loaded);
}
private HttpHeaders getFileResponseHeaders(String fileName) {
var headers = new HttpHeaders();
MediaType fileType = getFileType(fileName);
headers.setContentType(fileType);
// Files are requested with a version string in the URL, so their content cannot change
headers.setCacheControl(CacheControl.maxAge(30, TimeUnit.DAYS));
if (fileName.endsWith(".vsix")) {
headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
}
return headers;
}
@Test
public void testSetCacheabilityWhenCacheabilityIsSetToPrivate()
{
// Given
final CacheStrategy theCacheStrategy = CACHE_5_MINUTES;
final Cacheability setCacheability = PRIVATE;
// When
when( systemSettingManager.getSystemSetting( CACHEABILITY ) ).thenReturn( setCacheability );
final CacheControl actualCacheControl = webCache.getCacheControlFor( theCacheStrategy );
// Then
assertThat( actualCacheControl.toString().toLowerCase(), containsString( "private" ) );
}
@GetMapping("/prices")
public ResponseEntity<ItemPrice[]> prices()
{
MemoizedPrices memorizedPrices = this.memoizedPrices.get();
return ResponseEntity.ok()
.eTag(memorizedPrices.hash)
.cacheControl(CacheControl.maxAge(30, TimeUnit.MINUTES).cachePublic())
.body(memorizedPrices.prices);
}
@Test
public void testGetCacheControlForWhenCacheStrategyIsCache1Hour()
{
// Given
final CacheStrategy theCacheStrategy = CACHE_1_HOUR;
final CacheControl expectedCacheControl = stubPublicCacheControl( theCacheStrategy );
// When
when( systemSettingManager.getSystemSetting( CACHEABILITY ) ).thenReturn( PUBLIC );
final CacheControl actualCacheControl = webCache.getCacheControlFor( theCacheStrategy );
// Then
assertThat( actualCacheControl.toString(), is( expectedCacheControl.toString() ) );
}
@ResponseBody
@GetMapping(path = "/api.json", produces = "text/javascript")
public ResponseEntity<String> json(HttpServletRequest req, HttpServletResponse res) throws JsonProcessingException {
if (!utils.isApiEnabled()) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
Yaml yaml = new Yaml();
String yml = utils.loadResource("templates/api.yaml");
String result = ParaObjectUtils.getJsonWriter().writeValueAsString(yaml.load(yml));
return ResponseEntity.ok().cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS)).eTag(Utils.md5(result)).body(result);
}
protected void init() {
if (disableCaching) {
// fully disable cache in the browser
setCacheControl(CacheControl.noStore());
} else {
// make the browser check for changes before using a cached version
setCacheControl(CacheControl.noCache());
}
setRequireSession(false);
}
@Test
public void cacheControlTag() {
String body = "foo";
Mono<EntityResponse<String>>
result = EntityResponse.fromObject(body).cacheControl(CacheControl.noCache()).build();
StepVerifier.create(result)
.expectNextMatches(response -> "no-cache".equals(response.headers().getCacheControl()))
.expectComplete()
.verify();
}
@Test
public void cacheControl() {
assertThat(getHandler("/resources/**").getCacheControl(), Matchers.nullValue());
this.registration.setCacheControl(CacheControl.noCache().cachePrivate());
assertThat(getHandler("/resources/**").getCacheControl().getHeaderValue(),
Matchers.equalTo(CacheControl.noCache().cachePrivate().getHeaderValue()));
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 图片缓存 7 天
registry.addResourceHandler("/images/**")
.addResourceLocations(
"file:///" + imgFolder.replace("\\", "/"))
.setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS));
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException {
checkRequest(request);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
CacheControl cacheControl = lookupCacheControl(lookupPath);
Integer cacheSeconds = lookupCacheSeconds(lookupPath);
if (cacheControl != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying " + cacheControl);
}
applyCacheControl(response, cacheControl);
}
else if (cacheSeconds != null) {
if (logger.isTraceEnabled()) {
logger.trace("Applying cacheSeconds " + cacheSeconds);
}
applyCacheSeconds(response, cacheSeconds);
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Applying default cacheSeconds");
}
prepareResponse(response);
}
return true;
}
@Test
public void testResourcesWithResolversTransformersCustom() throws Exception {
loadBeanDefinitions("mvc-config-resources-chain-no-auto.xml", 12);
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
assertNotNull(mapping);
assertNotNull(mapping.getUrlMap().get("/resources/**"));
ResourceHttpRequestHandler handler = appContext.getBean((String) mapping.getUrlMap().get("/resources/**"),
ResourceHttpRequestHandler.class);
assertNotNull(handler);
assertThat(handler.getCacheControl().getHeaderValue(),
Matchers.equalTo(CacheControl.maxAge(1, TimeUnit.HOURS)
.sMaxAge(30, TimeUnit.MINUTES).cachePublic().getHeaderValue()));
List<ResourceResolver> resolvers = handler.getResourceResolvers();
assertThat(resolvers, Matchers.hasSize(3));
assertThat(resolvers.get(0), Matchers.instanceOf(VersionResourceResolver.class));
assertThat(resolvers.get(1), Matchers.instanceOf(GzipResourceResolver.class));
assertThat(resolvers.get(2), Matchers.instanceOf(PathResourceResolver.class));
VersionResourceResolver versionResolver = (VersionResourceResolver) resolvers.get(0);
assertThat(versionResolver.getStrategyMap().get("/**/*.js"),
Matchers.instanceOf(FixedVersionStrategy.class));
assertThat(versionResolver.getStrategyMap().get("/**"),
Matchers.instanceOf(ContentVersionStrategy.class));
List<ResourceTransformer> transformers = handler.getResourceTransformers();
assertThat(transformers, Matchers.hasSize(2));
assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class));
assertThat(transformers.get(1), Matchers.instanceOf(AppCacheManifestTransformer.class));
}
@Override
public <T> ResponseEntity<T> addCacheHeaders(final T body, final Instant lastModifiedTime) {
// Browsers can cache the templates for 1 hour, then they must check the last modified time with the server
final CacheControl cacheControl = CacheControl.maxAge(MAX_AGE_DAYS, TimeUnit.HOURS).mustRevalidate();
return ResponseEntity
.ok()
.cacheControl(cacheControl)
.lastModified(lastModifiedTime.toEpochMilli())
.body(body);
}
/**
* Apply the given cache seconds and generate corresponding HTTP headers,
* i.e. allow caching for the given number of seconds in case of a positive
* value, prevent caching if given a 0 value, do nothing else.
* Does not tell the browser to revalidate the resource.
* @param response current HTTP response
* @param cacheSeconds positive number of seconds into the future that the
* response should be cacheable for, 0 to prevent caching
*/
@SuppressWarnings("deprecation")
protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds) {
if (this.useExpiresHeader || !this.useCacheControlHeader) {
// Deprecated HTTP 1.0 cache behavior, as in previous Spring versions
if (cacheSeconds > 0) {
cacheForSeconds(response, cacheSeconds);
}
else if (cacheSeconds == 0) {
preventCaching(response);
}
}
else {
CacheControl cControl;
if (cacheSeconds > 0) {
cControl = CacheControl.maxAge(cacheSeconds, TimeUnit.SECONDS);
if (this.alwaysMustRevalidate) {
cControl = cControl.mustRevalidate();
}
}
else if (cacheSeconds == 0) {
cControl = (this.useCacheControlNoStore ? CacheControl.noStore() : CacheControl.noCache());
}
else {
cControl = CacheControl.empty();
}
applyCacheControl(response, cControl);
}
}
@Test
public void testGetAnalyticsCacheControlForWhenTimeToLiveIsNegative()
{
// Given
final long zeroTimeToLive = -1;
final Date aDate = new Date();
final CacheControl expectedCacheControl = noCache();
// When
when( analyticsCacheSettings.progressiveExpirationTimeOrDefault( aDate ) ).thenReturn( zeroTimeToLive );
final CacheControl actualCacheControl = webCache.getCacheControlFor( aDate );
// Then
assertThat( actualCacheControl.toString(), is( expectedCacheControl.toString() ) );
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/", "/index.html")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.noCache()).resourceChain(false)
.addResolver(new EncodedResourceResolver());
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS).cachePublic())
.resourceChain(false).addResolver(new EncodedResourceResolver());
}
@Test
public void cacheControl() {
assertThat(getHandler("/resources/**").getCacheControl(),
Matchers.nullValue());
this.registration.setCacheControl(CacheControl.noCache().cachePrivate());
assertThat(getHandler("/resources/**").getCacheControl().getHeaderValue(),
Matchers.equalTo(CacheControl.noCache().cachePrivate().getHeaderValue()));
}