亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

在Spring Boot中實現HTTP緩存的方法

2024-07-14 08:42:43
字體:
來源:轉載
供稿:網友

緩存是HTTP協議的一個強大功能,但由于某些原因,它主要用于靜態資源,如圖像,CSS樣式表或JavaScript文件,但是,HTTP緩存不僅限于這些,還可以將其用于動態計算的資源。

通過少量工作,您可以加快應用程序并改善整體用戶體驗。在本文中,您將學習 如何使用內置的HTTP響應緩存機制來實現緩存SpringBoot控制器的結果 。

1.如何以及何時使用HTTP響應緩存?

您可以在應用程序的多個層上進行緩存。數據庫具有其緩存存儲,Web客戶端也在其需要重用的信息。HTTP協議負責網絡通信。緩存機制允許我們通過減少客戶端和服務器之間傳輸的數據量來優化網絡流量。

何時優化: 當Web資源不經常更改或您確切知道何時更新時 ,就可以使用HTTP緩存進行優化。一旦確定了HTTP緩存的競爭者,就需要選擇合適的方法來管理緩存的驗證。 HTTP協議定義了幾個請求和響應標頭,您可以使用它們來控制客戶端何時清除緩存 。

選擇適當的HTTP標頭取決于您要優化的特定情況。但是無論用例如何,我們可以根據緩存的驗證發生在哪里進行緩存管理選項的劃分。

2.客戶端緩存驗證

當您知道請求的資源在給定的時間內不會更改時,服務器可以將此類信息作為響應標頭發送到客戶端。基于該信息,客戶端決定是否應該再次獲取資源或重用先前下載的資源。

有兩種可能的選項可以描述客戶端何時應該再次獲取資源并刪除存儲的緩存值。所以讓我們看看他們是如何運行的。

HTTP緩存在固定的時間內有效:如果要 阻止客戶端在指定時間內重新獲取資源 ,則應該使用 Cache-Control 標頭,可以在其中指定應該重新獲取所獲取數據的時間。

通過將標頭的值設置為 max-age = <seconds>, 可以通知客戶端多長時間不再需要再次獲取資源。 緩存值的有效性與請求的時間有關。

為了設置在Spring的控制器中的HTTP標頭,就要在RESTContoller用 ResponseEntity 包裝類 。

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

HTTP標頭的值只是一個常規字符串,但是 Cache-Control Spring為我們提供了一個特殊的構建器類,它可以防止我們犯下像拼寫錯誤這樣的小錯誤。

HTTP緩存有效到固定日期:有時您知道資源何時會發生變化。對于公布的數據而言,這是常見的情況,如天氣預報或昨天交易時段計算的股市指標。 資源的確切到期日期可以向客戶端公開。 應該使用 Expires HTTP標頭。應使用標準化數據格式 之一格式化日期值。

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(<font>"/forecast"</font><font>)ResponseEntity<Forecast> getTodaysForecast() {  </font><font><i>// ...</i></font><font>  ZonedDateTime expiresDate = ZonedDateTime.now().with(LocalTime.MAX);  String expires = expiresDate.format(DateTimeFormatter.RFC_1123_DATE_TIME);  <b>return</b> ResponseEntity.ok()      .header(HttpHeaders.EXPIRES, expires)      .body(weatherForecast);}</font>

請注意, HTTP日期格式需要有關時區的信息 。這就是上面的例子使用 ZonedDateTime的原因 。如果您嘗試使用 LocalDateTime ,則最終會在運行時出現以下錯誤消息:

java.time.temporal.UnsupportedTemporalTypeException:不支持的字段:OffsetSeconds

如果響應中存在 Cache-Control 和 Expires 標頭,則客戶端僅使用 Cache-Control 。

3.服務器端緩存驗證

在基于用戶輸入的動態生成的內容中,更常見的是服務器不知道何時將改變所請求的資源。在這種情況下,客戶端可以使用先前獲取的數據,但首先,它需要詢問服務器該數據是否仍然有效。

自第一次握手以來資源是否被修改?如果跟蹤Web資源的修改日期,則可以將此類日期作為響應的一部分公開給客戶端。在下一個請求中,客戶端將此日期發送回服務器,以便它可以驗證自上一個請求以來資源是否已被修改。如果資源未更改,則服務器不必再次重新發送數據。相反,它使用304 HTTP代碼響應,沒有任何有效負載。

要公開資源的修改日期,您應該設置 Last-Modified 標頭。Spring的ResponseEntity構建器有一個名為 lastModified() [url=https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseEntity.HeadersBuilder.html#lastModified-long-]的特殊方法[/url],它可以幫助您以正確的格式分配值。你會在一分鐘內看到這一點。

但 在發送完整響應之前,應檢查客戶端是否 在請求中 包含 If-Modified-Since 標頭 ??蛻舳烁鶕?Last-Modified 標頭的值設置其值,該標頭是與此特定資源的先前響應一起發送的。

如果 If-Modified-Since 標頭的值與所請求資源的修改日期匹配,則可以節省一些帶寬并使用空主體響應客戶端。

Spring再次提供了一個輔助方法,簡化了上述日期的比較。這個名為 checkNotModified()的 方法可以在 WebRequest 包裝器類中找到,您可以將其作為輸入添加到控制器的方法中。

讓我們仔細看看完整的例子。

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

首先,我們獲取所請求的資源并訪問其修改日期。我們將日期轉換為自格林威治標準時間1970年1月1日以來的毫秒數,因為這是Spring框架期望的格式。

然后,我們將日期與 If-Modified-Since 標頭的值進行比較,并在正匹配上返回一個空。否則,服務器發送具有 Last-Modified 標頭的適當值的完整響應主體。

憑借所有這些知識,您幾乎可以涵蓋所有常見的緩存設置選項。但是有一個更重要的機制你應該知道的是......

使用ETag進行資源版本控制

到目前為止,我們定義了有效期的精確度,精確度為1秒。但是如果你需要 更好的精度而不僅僅是一秒 呢?這就是ETag的用武之地。

可以將ETag定義為唯一的字符串值,該值在該時間點明確地標識資源。 通常,服務器根據給定資源的屬性計算ETag,或者,如果可用,則計算其最新修改日期。

客戶端和服務器之間的通信流程與修改日期檢查的情況幾乎相同。只有標題的名稱和值不同。

服務器在名為 ETag 的標題中設置ETag值。當客戶端再次訪問資源時,它應該在名為 If-None-Match 的頭中發送其值。如果該值與資源的新計算的ETag匹配,則服務器可以使用空內容和HTTP代碼304進行響應。

在Spring中,您可以實現ETag服務器流程,如下所示:

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

與前一個樣本幾乎相同,并且修改日期檢查。我們只是使用不同的值進行比較(以及MD5算法來計算ETag)。 請注意, WebRequest 有一個重載的 checkNotModified() 方法來處理表示為字符串的ETag。

如果 Last-Modified 和 ETag 工作幾乎相同,為什么我們需要兩者嗎?

Last-Modified vs ETag

正如我已經提到的, Last-Modified 標頭 不太精確, 因為它具有一秒的精度。為了獲得更高的精度,請選擇 ETag 。

當您不跟蹤 資源 的修改日期 時,您也被迫使用 ETag 。服務器可以根據資源的屬性計算其值。將其視為對象的哈希碼。

如果資源具有其修改日期并且您可以使用一秒精度,請使用 Last-Modified 標頭。為什么?因為 ETag計算可能是一項昂貴的操作 。

順便提一下,值得一提的是HTTP協議沒有指定用于計算ETag的算法。選擇算法時,您應該關注它的速度。

本文重點介紹緩存GET請求,但您應該知道服務器可以使用 ETag 來同步更新操作。

Spring ETag過濾器

因為ETag只是內容的字符串表示,所以服務器可以使用響應的字節表示來計算其值。意思是 你可以實際將ETag分配給任何響應。

Spring框架為您提供了ETag響應過濾器實現 ,它可以為您完成。您所要做的就是在應用程序中配置過濾器。

在Spring應用程序中添加HTTP過濾器的最簡單方法是通過配置類中的 FilterRegistrationBean 。

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

在這種情況下,對 addUrlPatterns() 的調用是多余的,因為默認情況下所有路徑都匹配。我把它放在這里證明你可以控制Spring應該添加ETag值的資源。

除了ETag生成之外,過濾器還會在可能的情況下響應HTTP 304和空體內容。

但要注意。

ETag計算可能很昂貴。 對于某些應用程序啟用此過濾器實際上可能會導致弊大于利 。在使用之前考慮一下您的解決方案。

結論

現在您已了解如何使用HTTP緩存優化應用程序,哪種方法最適合您,因為應用程序有不同的需求。

您了解到客戶端緩存驗證是最有效的方法,因為不涉及數據傳輸。在適用時,您應該始終支持客戶端緩存驗證。

我們還討論了服務器端驗證并比較了 Last-Modified 和 ETag 標頭。最后,您了解了如何在Spring應用程序中設置全局ETag過濾器。

總結

以上所述是小編給大家介紹的在Spring Boot中實現HTTP緩存的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美成人午夜激情在线| 精品成人久久av| 激情亚洲一区二区三区四区| 亚洲最大福利视频网站| 日韩一区二区在线视频| 国产一区二区久久精品| 欧美一级大片视频| 欧美性猛交xxxx| 国产精品亚洲аv天堂网| 欧美亚州一区二区三区| 欧美日韩激情小视频| 日韩免费黄色av| 韩国19禁主播vip福利视频| 日韩av在线免费观看一区| 久久精品电影网站| 亚洲国产精品yw在线观看| 久久影院资源网| 尤物九九久久国产精品的分类| 久久亚洲精品一区| 日韩欧美大尺度| 欧美一区第一页| 91国产视频在线播放| 国产视频在线观看一区二区| 日韩激情av在线免费观看| 欧美不卡视频一区发布| 亚洲日韩中文字幕在线播放| 国产精欧美一区二区三区| 668精品在线视频| 欧美激情视频网| www.久久撸.com| 91香蕉国产在线观看| 亚洲国产成人精品一区二区| 国产精品99蜜臀久久不卡二区| 国产精品久久婷婷六月丁香| 欧美激情欧美狂野欧美精品| 久久天天躁狠狠躁夜夜av| 日韩成人在线视频| 2019中文字幕在线免费观看| 国产一区二区三区视频免费| 日韩在线激情视频| 亚洲欧美日韩精品久久| 日韩精品极品在线观看播放免费视频| 精品网站999www| 日韩一区二区福利| 97视频网站入口| 亚洲国产成人在线视频| 亚洲综合中文字幕在线观看| 精品国产欧美一区二区五十路| 欧美二区在线播放| 久久青草精品视频免费观看| 91久久在线观看| 欧美色视频日本版| 亚洲国模精品一区| 久久精视频免费在线久久完整在线看| 尤物99国产成人精品视频| 成人久久一区二区| 亚洲偷欧美偷国内偷| 成人久久一区二区| 亚洲影视九九影院在线观看| 精品国产成人在线| 2018中文字幕一区二区三区| 欧美一级大片视频| 国模私拍一区二区三区| 国产精品永久免费视频| 色偷偷偷综合中文字幕;dd| 日韩成人av网| 亚洲图片欧美午夜| 色综合久久天天综线观看| 国产精品久久久999| 欧美猛交ⅹxxx乱大交视频| 欧美高清视频在线观看| 亚洲电影免费观看高清完整版在线观看| 精品国产91久久久| 亚洲视屏在线播放| 日韩欧美在线视频日韩欧美在线视频| 亚洲白拍色综合图区| 一区二区三区回区在观看免费视频| 国产精品嫩草视频| 91国内产香蕉| 伊人伊人伊人久久| 日韩在线观看免费网站| 欧美极品少妇xxxxⅹ裸体艺术| 日本成熟性欧美| 久久久黄色av| 亚洲日韩欧美视频一区| 成人中心免费视频| 国模精品视频一区二区| 热久久这里只有| 北条麻妃一区二区三区中文字幕| 国产精品高清免费在线观看| 欧美日韩性视频| 亚洲国产精品悠悠久久琪琪| 草民午夜欧美限制a级福利片| 国产精品劲爆视频| 亚洲电影免费观看高清完整版在线| 日韩精品中文字幕在线观看| 日韩精品在线观看网站| 亚洲有声小说3d| 国产综合色香蕉精品| 日韩精品在线免费观看| 91香蕉嫩草神马影院在线观看| 国产精品男女猛烈高潮激情| 国产精品91免费在线| 久久人人爽人人爽人人片av高清| 久久精品免费播放| 九九久久久久久久久激情| 亚洲香蕉av在线一区二区三区| 欧美高清videos高潮hd| 97av视频在线| 亚洲一区二区久久久| 欧美大尺度在线观看| 国产精品第二页| 精品人伦一区二区三区蜜桃免费| 一区二区三区四区在线观看视频| 欧美成年人在线观看| 亚洲free性xxxx护士hd| 日韩欧美中文第一页| 亚洲一品av免费观看| 中文国产成人精品久久一| 欧美日韩国产精品专区| 最近2019年日本中文免费字幕| 欧美成人剧情片在线观看| 亚洲二区中文字幕| 国产精品免费视频久久久| 欧美一区二区大胆人体摄影专业网站| 欧美日韩在线观看视频小说| 色偷偷av一区二区三区| 奇米四色中文综合久久| 国产午夜精品美女视频明星a级| 欧美大成色www永久网站婷| 日本精品久久久久久久| 日韩福利伦理影院免费| 亚洲成年网站在线观看| 国产精品av免费在线观看| 国产日韩综合一区二区性色av| 欧美激情第一页xxx| 亚洲欧美精品中文字幕在线| 欧美成人剧情片在线观看| 51精品国产黑色丝袜高跟鞋| 亚洲免费视频观看| 欧美壮男野外gaytube| 国产不卡在线观看| 日韩电影在线观看中文字幕| 欧美猛少妇色xxxxx| 亚洲精品一区二区在线| 成人免费观看49www在线观看| 91麻豆国产精品| 91chinesevideo永久地址| 亚洲天堂av女优| 国产69久久精品成人| 国产一区二区三区日韩欧美| 欧美有码在线观看| 欧美性视频精品| 久久精品91久久香蕉加勒比| 精品女厕一区二区三区| 亚洲欧美日韩中文在线制服| 亚洲色图欧美制服丝袜另类第一页| 国产精品欧美激情在线播放| 日韩国产一区三区| 亚洲精品美女免费| 日韩在线不卡视频| 欧美最顶级的aⅴ艳星| 日韩免费观看高清| 8050国产精品久久久久久|