溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringMVC中的http Caching怎么用

發(fā)布時(shí)間:2021-09-02 13:45:09 來源:億速云 閱讀:203 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要為大家展示了“SpringMVC中的http Caching怎么用”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“SpringMVC中的http Caching怎么用”這篇文章吧。

Cache 是HTTP協(xié)議中的一個(gè)非常重要的功能,使用Cache可以大大提高應(yīng)用程序的性能,減少數(shù)據(jù)的網(wǎng)絡(luò)傳輸。

通常來說我們會(huì)對(duì)靜態(tài)資源比如:圖片,CSS,JS文件等做緩存。同樣的我們可以使用HTTP Cache配合Spring MVC來做動(dòng)態(tài)資源的緩存。

那么什么時(shí)候使用動(dòng)態(tài)資源的緩存呢?

只有當(dāng)這個(gè)資源不經(jīng)常更新或者你確切的知道該資源什么時(shí)候更新的時(shí)候就可以使用HTTP Cache了。

HTTP Cache是通過請(qǐng)求頭來實(shí)現(xiàn)的,主要有三種方式:過期時(shí)間,最后更新時(shí)間和Etag。

其中過期時(shí)間是客戶端驗(yàn)證,最后更新時(shí)間和Etag是服務(wù)器端驗(yàn)證。

過期時(shí)間

過期時(shí)間又有兩種方式,分別是Cache-Control和Expires頭。

在Cache-Control中,我們可以設(shè)置它的maxAge,超出該時(shí)間后,該資源才會(huì)被再次請(qǐng)求。如下所示:

@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable long id) {
   // …
   CacheControl cacheControl = CacheControl.maxAge(30, TimeUnit.MINUTES);
   return ResponseEntity.ok()
           .cacheControl(cacheControl)
           .body(product);
}

我們也可以在Head中設(shè)置Expires屬性。Expires的時(shí)間需要是標(biāo)準(zhǔn)時(shí)間格式,如下:

Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format

如果要在java中使用,參考如下的例子:

@GetMapping("/forecast")
ResponseEntity<Forecast> getTodaysForecast() {
   // ...
   ZonedDateTime expiresDate = ZonedDateTime.now().with(LocalTime.MAX);
   String expires = expiresDate.format(DateTimeFormatter.RFC_1123_DATE_TIME);
   return ResponseEntity.ok()
           .header(HttpHeaders.EXPIRES, expires)
           .body(weatherForecast);
}

如果Cache-Control和Expires同時(shí)出現(xiàn),則會(huì)優(yōu)先使用 Cache-Control。

Last-Modified

它的驗(yàn)證邏輯是這樣的,客戶端會(huì)根據(jù)上次請(qǐng)求得到的Last-Modified設(shè)置它的If-Modified-Since,服務(wù)器端接收到了這個(gè)屬性之后可以跟之前的進(jìn)行比較,如果相同則可以返回一個(gè)空的body。如下所示:

@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable long id, WebRequest request) {
   Product product = repository.find(id);
   long modificationDate = product.getModificationDate()
           .toInstant().toEpochMilli();
 
   if (request.checkNotModified(modificationDate)) {
       return null;
   }
 
   return ResponseEntity.ok()
           .lastModified(modificationDate)
           .body(product);
}

ETag

Last-Modified的時(shí)間只能精確到秒,如果還需要更細(xì)粒度的話,就需要用到ETag了。

ETag可以看成當(dāng)前時(shí)刻某個(gè)資源的唯一標(biāo)記,你可以取該資源的hash值作為ETag。

下面是它的一種實(shí)現(xiàn):

@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable long id, WebRequest request) {
   Product product = repository.find(id);
   String modificationDate = product.getModificationDate().toString();
   String eTag = DigestUtils.md5DigestAsHex(modificationDate.getBytes());
 
   if (request.checkNotModified(eTag)) {
       return null;
   }
 
   return ResponseEntity.ok()
           .eTag(eTag)
           .body(product);
}

Spring ETag filter

Spring提供了一個(gè)ShallowEtagHeaderFilter來根據(jù)返回的內(nèi)容自動(dòng)為你生成Etag。

@Bean
public FilterRegistrationBean filterRegistrationBean () {
   ShallowEtagHeaderFilter eTagFilter = new ShallowEtagHeaderFilter();
   FilterRegistrationBean registration = new FilterRegistrationBean();
   registration.setFilter(eTagFilter);
   registration.addUrlPatterns("/*");
   return registration;
}

請(qǐng)注意, ETag計(jì)算可能會(huì)影響性能。

以上是“SpringMVC中的http Caching怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI