@@ -2542,6 +2542,124 @@ include::webflux-view.adoc[leveloffset=+1]
2542
2542
2543
2543
2544
2544
2545
+ [[webflux-caching]]
2546
+ == HTTP Caching
2547
+ [.small]#<<web.adoc#mvc-caching,Same in Spring MVC>>#
2548
+
2549
+ HTTP caching can significantly improve the performance of a web application. HTTP caching
2550
+ revolves around the "Cache-Control" response header and subsequently conditional request
2551
+ headers such as "Last-Modified" and "ETag". "Cache-Control" advises private (e.g. browser)
2552
+ and public (e.g. proxy) caches how to cache and re-use responses. An "ETag" header is used
2553
+ to make a conditional request that may result in a 304 (NOT_MODIFIED) without a body,
2554
+ if the content has not changed. "ETag" can be seen as a more sophisticated successor to
2555
+ the `Last-Modified` header.
2556
+
2557
+ This section describes HTTP caching related options available in Spring Web MVC.
2558
+
2559
+
2560
+
2561
+ [[webflux-caching-cachecontrol]]
2562
+ === `CacheControl`
2563
+ [.small]#<<web.adoc#mvc-caching-cachecontrol,Same in Spring MVC>>#
2564
+
2565
+ {api-spring-framework}/http/CacheControl.html[`CacheControl`] provides support for
2566
+ configuring settings related to the "Cache-Control" header and is accepted as an argument
2567
+ in a number of places:
2568
+
2569
+ * <<webflux-caching-etag-lastmodified>>
2570
+ * <<webflux-caching-static-resources>>
2571
+
2572
+ While https://tools.ietf.org/html/rfc7234#section-5.2.2[RFC 7234] describes all possible
2573
+ directives for the "Cache-Control" response header, the `CacheControl` type takes a
2574
+ use case oriented approach focusing on the common scenarios:
2575
+
2576
+ [source,java,indent=0]
2577
+ [subs="verbatim,quotes"]
2578
+ ----
2579
+ // Cache for an hour - "Cache-Control: max-age=3600"
2580
+ CacheControl ccCacheOneHour = CacheControl.maxAge(1, TimeUnit.HOURS);
2581
+
2582
+ // Prevent caching - "Cache-Control: no-store"
2583
+ CacheControl ccNoStore = CacheControl.noStore();
2584
+
2585
+ // Cache for ten days in public and private caches,
2586
+ // public caches should not transform the response
2587
+ // "Cache-Control: max-age=864000, public, no-transform"
2588
+ CacheControl ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic();
2589
+ ----
2590
+
2591
+
2592
+
2593
+ [[webflux-caching-etag-lastmodified]]
2594
+ === Controllers
2595
+ [.small]#<<web.adoc#mvc-caching-etag-lastmodified,Same in Spring MVC>>#
2596
+
2597
+ Controllers can add explicit support for HTTP caching. This is recommended since the
2598
+ lastModified or ETag value for a resource needs to be calculated before it can be compared
2599
+ against conditional request headers. A controller can add an ETag and "Cache-Control"
2600
+ settings to a `ResponseEntity`:
2601
+
2602
+ [source,java,indent=0]
2603
+ [subs="verbatim,quotes"]
2604
+ ----
2605
+ @GetMapping("/book/{id}")
2606
+ public ResponseEntity<Book> showBook(@PathVariable Long id) {
2607
+
2608
+ Book book = findBook(id);
2609
+ String version = book.getVersion();
2610
+
2611
+ return ResponseEntity
2612
+ .ok()
2613
+ .cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
2614
+ .eTag(version) // lastModified is also available
2615
+ .body(book);
2616
+ }
2617
+ ----
2618
+
2619
+ This will send an 304 (NOT_MODIFIED) response with an empty body, if the comparison
2620
+ to the conditional request headers indicates the content has not changed. Otherwise the
2621
+ "ETag" and "Cache-Control" headers will be added to the response.
2622
+
2623
+ The check against conditional request headers can also be made in the controller:
2624
+
2625
+ [source,java,indent=0]
2626
+ [subs="verbatim,quotes"]
2627
+ ----
2628
+ @RequestMapping
2629
+ public String myHandleMethod(ServerWebExchange exchange, Model model) {
2630
+
2631
+ long eTag = ... <1>
2632
+
2633
+ if (exchange.checkNotModified(eTag)) {
2634
+ return null; <2>
2635
+ }
2636
+
2637
+ model.addAttribute(...); <3>
2638
+ return "myViewName";
2639
+ }
2640
+ ----
2641
+
2642
+ <1> Application-specific calculation.
2643
+ <2> Response has been set to 304 (NOT_MODIFIED), no further processing.
2644
+ <3> Continue with request processing.
2645
+
2646
+ There are 3 variants for checking conditional requests against eTag values, lastModified
2647
+ values, or both. For conditional "GET" and "HEAD" requests, the response may be set to
2648
+ 304 (NOT_MODIFIED). For conditional "POST", "PUT", and "DELETE", the response would be set
2649
+ to 409 (PRECONDITION_FAILED) instead to prevent concurrent modification.
2650
+
2651
+
2652
+
2653
+ [[webflux-caching-static-resources]]
2654
+ === Static resources
2655
+ [.small]#<<web.adoc#mvc-caching-static-resources,Same in Spring MVC>>#
2656
+
2657
+ Static resources should be served with a "Cache-Control" and conditional response headers
2658
+ for optimal performance. See section on configuring <<webflux-config-static-resources>>.
2659
+
2660
+
2661
+
2662
+
2545
2663
[[webflux-config]]
2546
2664
== WebFlux Config
2547
2665
[.small]#<<web.adoc#mvc-config,Same in Spring MVC>>#
0 commit comments