控制器可以增加对 HTTP 缓存的明确支持。我们推荐这样做,因为资源的 lastModified 或 ETag 值需要在与条件请求头进行比较之前进行计算。控制器可以为 ResponseEntity 添加 ETag 头和 Cache-Control 设置,如下例所示:
@GetMapping("/book/{id}")public ResponseEntity<Book> showBook(@PathVariable Long id) {Book book = findBook(id);String version = book.getVersion();return ResponseEntity.ok().cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS)).eTag(version) // lastModified 也是可用的.body(book);}
如果与条件请求头的比较表明内容没有改变,前面的例子会发送一个 304(NOT_MODIFIED)响应,并有一个空的正文。否则,ETag 和 Cache-Control 头信息将被添加到响应中。
你也可以在控制器中对条件请求头进行检查,如下面的例子所示:
@RequestMappingpublic String myHandleMethod(WebRequest request, Model model) {// 特定的应用计算,比如可以用文件的 哈希值,或则数据库中存储的版本字段,或则文件的修改时间等,都可以用来做 eTaglong eTag = ...if (request.checkNotModified(eTag)) {// 响应会被设置为 304(NOT_MODIFIED),不需要进一步处理return null;}// 继续进行请求处理。model.addAttribute(...);return "myViewName";}
有三种变体用于根据 eTag 值、lastModified 值或两者检查条件性请求。对于有条件的 GET 和 HEAD 请求,你可以将响应设置为 304(NOT_MODIFIED)。对于有条件的 POST、PUT 和 DELETE 请求,你可以将响应设置为 412(PRECONDITION_FAILED),以防止并发的修改。
