Spring MVC 在控制器中設(shè)置Cache-Control、ETag和Last-Modified響應頭

2018-07-26 14:45 更新

控制器能處理帶有'Cache-Control'、'ETag'及/或'If-Modified-Since'頭的請求,如果服務端在響應中設(shè)置了'Cache-Control'響應頭,那么我們推薦在控制器內(nèi)對這些請求頭進行處理。這涉及一些工作:計算最后更改時間long和/或請求的ETag值、與請求頭的'If-Modified-Since'值做比較,并且在資源未更改的情況下在響應中返回一個304(資源未更改)狀態(tài)碼。

正如在"使用HttpEntity"一節(jié)中所講,控制器可以通過HttpEntity類與請求/響應交互。返回ResponseEntity的控制器可以在響應中包含HTTP緩存的信息,如下代碼所示:

@RequestMapping("/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);
}

這樣做不僅會在響應頭中設(shè)置'ETag''Cache-Control'相關(guān)的信息,同時也會 嘗試將響應狀態(tài)碼設(shè)置為HTTP 304 Not Modified(資源未修改)及將響應體置空——如果客戶端攜帶的請求頭信息與控制器設(shè)置的緩存信息能夠匹配的話。

如果希望在@RequestMapping方法上也能完成同樣的事,那么你可以這樣做:

@RequestMapping
public String myHandleMethod(WebRequest webRequest, Model model) {

    long lastModified = // 1. 應用相關(guān)的方式計算得到(application-specific calculation)

    if (request.checkNotModified(lastModified)) {
        // 2. 快速退出 — 不需要更多處理了
        return null;
    }

    // 3. 若資源更改了,那么再進行請求處理階段,一般而言是準備響應內(nèi)容
    model.addAttribute(...);
    return "myViewName";
}

這里最重要的兩個地方是:調(diào)用request.checkNotModified(lastModified)方法,以及返回null。前者(方法調(diào)用)在返回true之前會將響應狀態(tài)碼設(shè)為304;而后者,在檢查是否更改的方法調(diào)用返回true的基礎(chǔ)上直接將方法返回,這會通知Spring MVC不再對請求做任何處理。

另外要注意的是,檢查資源是否發(fā)生了更改有3種方式:

  • request.checkNotModified(lastModified)方法會將傳入的參數(shù)值(最后修改時間)與請求頭'If-Modified-Since'的值進行比較
  • request.checkNotModified(eTag)方法會將傳入的參數(shù)值與請求頭'ETag'的值進行比較
  • request.checkNotModified(eTag, lastModified)方法會同時進行以上兩種比較。也即是說,只有在兩個比較都被判定為未修改時,服務器才會返回一個304響應狀態(tài)碼HTTP 304 Not Modified(資源未修改)


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號