19
19
import java .time .Duration ;
20
20
import java .time .temporal .ChronoUnit ;
21
21
import java .util .concurrent .TimeUnit ;
22
- import java .util .function .BiFunction ;
23
- import java .util .function .Supplier ;
24
-
25
- import javax .annotation .PostConstruct ;
26
22
27
23
import org .springframework .boot .context .properties .ConfigurationProperties ;
28
- import org .springframework .boot .context .properties .NestedConfigurationProperty ;
29
24
import org .springframework .boot .context .properties .bind .convert .DurationUnit ;
30
25
import org .springframework .http .CacheControl ;
31
- import org .springframework .util .Assert ;
32
26
33
27
/**
34
28
* Properties used to configure resource handling.
@@ -45,7 +39,7 @@ public class ResourceProperties {
45
39
46
40
private static final String [] CLASSPATH_RESOURCE_LOCATIONS = {
47
41
"classpath:/META-INF/resources/" , "classpath:/resources/" ,
48
- "classpath:/static/" , "classpath:/public/" };
42
+ "classpath:/static/" , "classpath:/public/" };
49
43
50
44
/**
51
45
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
@@ -54,17 +48,18 @@ public class ResourceProperties {
54
48
private String [] staticLocations = CLASSPATH_RESOURCE_LOCATIONS ;
55
49
56
50
/**
57
- * Cache period for the resources served by the resource handler. If a duration suffix
58
- * is not specified, seconds will be used.
51
+ * Cache period for the resources served by the resource handler.
52
+ * If a duration suffix is not specified, seconds will be used.
53
+ * Can be overridden by the {@code cache-control} property.
59
54
*/
60
55
@ DurationUnit (ChronoUnit .SECONDS )
61
56
private Duration cachePeriod ;
62
57
63
58
/**
64
- * Cache control headers. Either {@link #cachePeriod} or {@link #cacheControl} can be set.
59
+ * Cache control HTTP headers, only allows valid directive combinations.
60
+ * Overrides the {@code cache-period} property.
65
61
*/
66
- @ NestedConfigurationProperty
67
- private CacheControlProperties cacheControl ;
62
+ private CacheControlProperties cacheControl = new CacheControlProperties ();
68
63
69
64
/**
70
65
* Enable default resource handling.
@@ -106,7 +101,6 @@ public void setCacheControl(CacheControlProperties cacheControl) {
106
101
this .cacheControl = cacheControl ;
107
102
}
108
103
109
-
110
104
public boolean isAddMappings () {
111
105
return this .addMappings ;
112
106
}
@@ -119,36 +113,6 @@ public Chain getChain() {
119
113
return this .chain ;
120
114
}
121
115
122
- public CacheControl createCacheControl () {
123
- if (this .cachePeriod != null ) {
124
- return CacheControl .maxAge (this .cachePeriod .getSeconds (), TimeUnit .SECONDS );
125
- }
126
- if (this .cacheControl != null ) {
127
- return this .cacheControl .transformToHttpSpringCacheControl ();
128
- }
129
- return null ;
130
- }
131
-
132
- @ PostConstruct
133
- public void checkIncompatibleCacheOptions () {
134
- Assert .state (this .cachePeriod == null || this .cacheControl == null ,
135
- "Only one of cache-period or cache-control may be set." );
136
- if (this .cacheControl != null ) {
137
- if (this .cacheControl .getMaxAge () != null ) {
138
- Assert .state (!Boolean .TRUE .equals (this .cacheControl .getNoCache ()), "no-cache may not be set if max-age is set." );
139
- Assert .state (!Boolean .TRUE .equals (this .cacheControl .getNoStore ()), "no-store may not be set if max-age is set." );
140
- }
141
- if (this .cacheControl .getNoCache () != null ) {
142
- Assert .state (this .cacheControl .getMaxAge () == null , "max-age may not be set if no-cache is set." );
143
- Assert .state (!Boolean .TRUE .equals (this .cacheControl .getNoStore ()), "no-store may not be set if no-cache is set." );
144
- }
145
- if (this .cacheControl .getNoStore () != null ) {
146
- Assert .state (this .cacheControl .getMaxAge () == null , "max-age may not be set if no-store is set." );
147
- Assert .state (!Boolean .TRUE .equals (this .cacheControl .getNoCache ()), "no-cache may not be set if no-store is set." );
148
- }
149
- }
150
- }
151
-
152
116
/**
153
117
* Configuration for the Spring Resource Handling chain.
154
118
*/
@@ -328,38 +292,83 @@ public void setVersion(String version) {
328
292
}
329
293
330
294
/**
331
- * Configuration for the Cache Control header.
295
+ * Configuration for the Cache Control HTTP header.
332
296
*/
333
-
334
297
public static class CacheControlProperties {
335
298
336
- private Long maxAge ;
299
+ /**
300
+ * Maximum time the response should be cached,
301
+ * in seconds if no duration suffix is not specified.
302
+ */
303
+ @ DurationUnit (ChronoUnit .SECONDS )
304
+ private Duration maxAge ;
337
305
306
+ /**
307
+ * Indicate that the cached response can be reused only
308
+ * if re-validated with the server.
309
+ */
338
310
private Boolean noCache ;
339
311
312
+ /**
313
+ * Indicate to not cache the response in any case.
314
+ */
340
315
private Boolean noStore ;
341
316
317
+ /**
318
+ * Indicate that once it has become stale, a cache must not use
319
+ * the response without re-validating it with the server.
320
+ */
342
321
private Boolean mustRevalidate ;
343
322
323
+ /**
324
+ * Indicate intermediaries (caches and others) that they should
325
+ * not transform the response content.
326
+ */
344
327
private Boolean noTransform ;
345
328
329
+ /**
330
+ * Indicate that any cache may store the response.
331
+ */
346
332
private Boolean cachePublic ;
347
333
334
+ /**
335
+ * Indicate that the response message is intended for a single user
336
+ * and must not be stored by a shared cache.
337
+ */
348
338
private Boolean cachePrivate ;
349
339
340
+ /**
341
+ * Same meaning as the "must-revalidate" directive,
342
+ * except that it does not apply to private caches.
343
+ */
350
344
private Boolean proxyRevalidate ;
351
345
352
- private Long staleWhileRevalidate ;
346
+ /**
347
+ * Maximum time the response can be served after it becomes stale,
348
+ * in seconds if no duration suffix is not specified.
349
+ */
350
+ @ DurationUnit (ChronoUnit .SECONDS )
351
+ private Duration staleWhileRevalidate ;
353
352
354
- private Long staleIfError ;
353
+ /**
354
+ * Maximum time the response may be used when errors are encountered,
355
+ * in seconds if no duration suffix is not specified.
356
+ */
357
+ @ DurationUnit (ChronoUnit .SECONDS )
358
+ private Duration staleIfError ;
355
359
356
- private Long sMaxAge ;
360
+ /**
361
+ * Maximum time the response should be cached by shared caches,
362
+ * in seconds if no duration suffix is not specified.
363
+ */
364
+ @ DurationUnit (ChronoUnit .SECONDS )
365
+ private Duration sMaxAge ;
357
366
358
- public Long getMaxAge () {
367
+ public Duration getMaxAge () {
359
368
return this .maxAge ;
360
369
}
361
370
362
- public void setMaxAge (Long maxAge ) {
371
+ public void setMaxAge (Duration maxAge ) {
363
372
this .maxAge = maxAge ;
364
373
}
365
374
@@ -419,91 +428,71 @@ public void setProxyRevalidate(Boolean proxyRevalidate) {
419
428
this .proxyRevalidate = proxyRevalidate ;
420
429
}
421
430
422
- public Long getStaleWhileRevalidate () {
431
+ public Duration getStaleWhileRevalidate () {
423
432
return this .staleWhileRevalidate ;
424
433
}
425
434
426
- public void setStaleWhileRevalidate (Long staleWhileRevalidate ) {
435
+ public void setStaleWhileRevalidate (Duration staleWhileRevalidate ) {
427
436
this .staleWhileRevalidate = staleWhileRevalidate ;
428
437
}
429
438
430
- public Long getStaleIfError () {
439
+ public Duration getStaleIfError () {
431
440
return this .staleIfError ;
432
441
}
433
442
434
- public void setStaleIfError (Long staleIfError ) {
443
+ public void setStaleIfError (Duration staleIfError ) {
435
444
this .staleIfError = staleIfError ;
436
445
}
437
446
438
- public Long getsMaxAge () {
447
+ public Duration getsMaxAge () {
439
448
return this .sMaxAge ;
440
449
}
441
450
442
- public void setsMaxAge (Long sMaxAge ) {
451
+ public void setsMaxAge (Duration sMaxAge ) {
443
452
this .sMaxAge = sMaxAge ;
444
453
}
445
454
446
- CacheControl transformToHttpSpringCacheControl () {
447
- CacheControl httpSpringCacheControl = initCacheControl ();
448
- httpSpringCacheControl = setFlags (httpSpringCacheControl );
449
- httpSpringCacheControl = setTimes (httpSpringCacheControl );
450
- return httpSpringCacheControl ;
451
- }
452
-
453
- private CacheControl initCacheControl () {
454
- if (this .maxAge != null ) {
455
- return CacheControl .maxAge (this .maxAge , TimeUnit .SECONDS );
455
+ public CacheControl toHttpCacheControl () {
456
+ CacheControl cc ;
457
+ if (Boolean .TRUE .equals (this .noStore )) {
458
+ cc = CacheControl .noStore ();
456
459
}
457
- if (Boolean .TRUE .equals (this .noCache )) {
458
- return CacheControl .noCache ();
460
+ else if (Boolean .TRUE .equals (this .noCache )) {
461
+ cc = CacheControl .noCache ();
459
462
}
460
- if (Boolean . TRUE . equals ( this .noStore ) ) {
461
- return CacheControl .noStore ( );
463
+ else if (this .maxAge != null ) {
464
+ cc = CacheControl .maxAge ( this . maxAge . getSeconds (), TimeUnit . SECONDS );
462
465
}
463
- return CacheControl .empty ();
464
- }
465
-
466
- private CacheControl setFlags (CacheControl cacheControl ) {
467
- cacheControl = setBoolean (this .mustRevalidate , cacheControl ::mustRevalidate ,
468
- cacheControl );
469
- cacheControl = setBoolean (this .noTransform , cacheControl ::noTransform ,
470
- cacheControl );
471
- cacheControl = setBoolean (this .cachePublic , cacheControl ::cachePublic ,
472
- cacheControl );
473
- cacheControl = setBoolean (this .cachePrivate , cacheControl ::cachePrivate ,
474
- cacheControl );
475
- cacheControl = setBoolean (this .proxyRevalidate , cacheControl ::proxyRevalidate ,
476
- cacheControl );
477
- return cacheControl ;
478
- }
479
-
480
- private static CacheControl setBoolean (Boolean value ,
481
- Supplier <CacheControl > setter , CacheControl cacheControl ) {
482
- if (Boolean .TRUE .equals (value )) {
483
- return setter .get ();
466
+ else {
467
+ cc = CacheControl .empty ();
484
468
}
485
- return cacheControl ;
486
- }
487
-
488
- private CacheControl setTimes (CacheControl cacheControl ) {
489
- cacheControl = setLong (this .staleWhileRevalidate ,
490
- cacheControl ::staleWhileRevalidate , cacheControl );
491
- cacheControl = setLong (this .staleIfError , cacheControl ::staleIfError ,
492
- cacheControl );
493
- cacheControl = setLong (this .sMaxAge , cacheControl ::sMaxAge , cacheControl );
494
- return cacheControl ;
495
- }
496
-
497
- private static CacheControl setLong (Long value ,
498
- BiFunction <Long , TimeUnit , CacheControl > setter ,
499
- CacheControl cacheControl ) {
500
- if (value != null ) {
501
- return setter .apply (value , TimeUnit .SECONDS );
469
+ if (Boolean .TRUE .equals (this .mustRevalidate )) {
470
+ cc .mustRevalidate ();
471
+ }
472
+ if (Boolean .TRUE .equals (this .noTransform )) {
473
+ cc .noTransform ();
474
+ }
475
+ if (Boolean .TRUE .equals (this .cachePublic )) {
476
+ cc .cachePublic ();
502
477
}
503
- return cacheControl ;
478
+ if (Boolean .TRUE .equals (this .cachePrivate )) {
479
+ cc .cachePrivate ();
480
+ }
481
+ if (Boolean .TRUE .equals (this .proxyRevalidate )) {
482
+ cc .proxyRevalidate ();
483
+ }
484
+ if (this .staleWhileRevalidate != null ) {
485
+ cc .staleWhileRevalidate (this .staleWhileRevalidate .getSeconds (), TimeUnit .SECONDS );
486
+ }
487
+ if (this .staleIfError != null ) {
488
+ cc .staleIfError (this .staleIfError .getSeconds (), TimeUnit .SECONDS );
489
+ }
490
+ if (this .sMaxAge != null ) {
491
+ cc .sMaxAge (this .sMaxAge .getSeconds (), TimeUnit .SECONDS );
492
+ }
493
+ return cc ;
504
494
}
505
495
506
496
}
507
497
508
-
509
498
}
0 commit comments