最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在Spring Boot中實(shí)現(xiàn)HTTP緩存的方法

 更新時(shí)間:2018年10月30日 16:52:40   作者:banq  
緩存是HTTP協(xié)議的一個(gè)強(qiáng)大功能,但由于某些原因,它主要用于靜態(tài)資源,如圖像,CSS樣式表或JavaScript文件。本文重點(diǎn)給大家介紹在Spring Boot中實(shí)現(xiàn)HTTP緩存的方法,感興趣的朋友跟隨小編一起看看吧

緩存是HTTP協(xié)議的一個(gè)強(qiáng)大功能,但由于某些原因,它主要用于靜態(tài)資源,如圖像,CSS樣式表或JavaScript文件,但是,HTTP緩存不僅限于這些,還可以將其用于動(dòng)態(tài)計(jì)算的資源。

通過(guò)少量工作,您可以加快應(yīng)用程序并改善整體用戶(hù)體驗(yàn)。在本文中,您將學(xué)習(xí) 如何使用內(nèi)置的HTTP響應(yīng)緩存機(jī)制來(lái)實(shí)現(xiàn)緩存SpringBoot控制器的結(jié)果 。

1.如何以及何時(shí)使用HTTP響應(yīng)緩存?

您可以在應(yīng)用程序的多個(gè)層上進(jìn)行緩存。數(shù)據(jù)庫(kù)具有其緩存存儲(chǔ),Web客戶(hù)端也在其需要重用的信息。HTTP協(xié)議負(fù)責(zé)網(wǎng)絡(luò)通信。緩存機(jī)制允許我們通過(guò)減少客戶(hù)端和服務(wù)器之間傳輸?shù)臄?shù)據(jù)量來(lái)優(yōu)化網(wǎng)絡(luò)流量。

何時(shí)優(yōu)化: 當(dāng)Web資源不經(jīng)常更改或您確切知道何時(shí)更新時(shí) ,就可以使用HTTP緩存進(jìn)行優(yōu)化。一旦確定了HTTP緩存的競(jìng)爭(zhēng)者,就需要選擇合適的方法來(lái)管理緩存的驗(yàn)證。 HTTP協(xié)議定義了幾個(gè)請(qǐng)求和響應(yīng)標(biāo)頭,您可以使用它們來(lái)控制客戶(hù)端何時(shí)清除緩存 。

選擇適當(dāng)?shù)腍TTP標(biāo)頭取決于您要優(yōu)化的特定情況。但是無(wú)論用例如何,我們可以根據(jù)緩存的驗(yàn)證發(fā)生在哪里進(jìn)行緩存管理選項(xiàng)的劃分。

2.客戶(hù)端緩存驗(yàn)證

當(dāng)您知道請(qǐng)求的資源在給定的時(shí)間內(nèi)不會(huì)更改時(shí),服務(wù)器可以將此類(lèi)信息作為響應(yīng)標(biāo)頭發(fā)送到客戶(hù)端。基于該信息,客戶(hù)端決定是否應(yīng)該再次獲取資源或重用先前下載的資源。

有兩種可能的選項(xiàng)可以描述客戶(hù)端何時(shí)應(yīng)該再次獲取資源并刪除存儲(chǔ)的緩存值。所以讓我們看看他們是如何運(yùn)行的。

HTTP緩存在固定的時(shí)間內(nèi)有效:如果要 阻止客戶(hù)端在指定時(shí)間內(nèi)重新獲取資源 ,則應(yīng)該使用 Cache-Control 標(biāo)頭,可以在其中指定應(yīng)該重新獲取所獲取數(shù)據(jù)的時(shí)間。

通過(guò)將標(biāo)頭的值設(shè)置為 max-age = <seconds>, 可以通知客戶(hù)端多長(zhǎng)時(shí)間不再需要再次獲取資源。 緩存值的有效性與請(qǐng)求的時(shí)間有關(guān)。

為了設(shè)置在Spring的控制器中的HTTP標(biāo)頭,就要在RESTContoller用 ResponseEntity 包裝類(lèi) 。

@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標(biāo)頭的值只是一個(gè)常規(guī)字符串,但是 Cache-Control Spring為我們提供了一個(gè)特殊的構(gòu)建器類(lèi),它可以防止我們犯下像拼寫(xiě)錯(cuò)誤這樣的小錯(cuò)誤。

HTTP緩存有效到固定日期:有時(shí)您知道資源何時(shí)會(huì)發(fā)生變化。對(duì)于公布的數(shù)據(jù)而言,這是常見(jiàn)的情況,如天氣預(yù)報(bào)或昨天交易時(shí)段計(jì)算的股市指標(biāo)。 資源的確切到期日期可以向客戶(hù)端公開(kāi)。 應(yīng)該使用 Expires HTTP標(biāo)頭。應(yīng)使用標(biāo)準(zhǔn)化數(shù)據(jù)格式 之一格式化日期值。

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

幸運(yùn)的是,Java附帶了第一個(gè)這些格式的預(yù)定義格式化程序??梢栽谙旅嬲业綄?biāo)題設(shè)置為當(dāng)天結(jié)束的示例。

@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>

請(qǐng)注意, HTTP日期格式需要有關(guān)時(shí)區(qū)的信息 。這就是上面的例子使用 ZonedDateTime的原因 。如果您嘗試使用 LocalDateTime ,則最終會(huì)在運(yùn)行時(shí)出現(xiàn)以下錯(cuò)誤消息:

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

如果響應(yīng)中存在 Cache-Control 和 Expires 標(biāo)頭,則客戶(hù)端僅使用 Cache-Control 。

3.服務(wù)器端緩存驗(yàn)證

在基于用戶(hù)輸入的動(dòng)態(tài)生成的內(nèi)容中,更常見(jiàn)的是服務(wù)器不知道何時(shí)將改變所請(qǐng)求的資源。在這種情況下,客戶(hù)端可以使用先前獲取的數(shù)據(jù),但首先,它需要詢(xún)問(wèn)服務(wù)器該數(shù)據(jù)是否仍然有效。

自第一次握手以來(lái)資源是否被修改?如果跟蹤Web資源的修改日期,則可以將此類(lèi)日期作為響應(yīng)的一部分公開(kāi)給客戶(hù)端。在下一個(gè)請(qǐng)求中,客戶(hù)端將此日期發(fā)送回服務(wù)器,以便它可以驗(yàn)證自上一個(gè)請(qǐng)求以來(lái)資源是否已被修改。如果資源未更改,則服務(wù)器不必再次重新發(fā)送數(shù)據(jù)。相反,它使用304 HTTP代碼響應(yīng),沒(méi)有任何有效負(fù)載。

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

但 在發(fā)送完整響應(yīng)之前,應(yīng)檢查客戶(hù)端是否 在請(qǐng)求中 包含 If-Modified-Since 標(biāo)頭 ??蛻?hù)端根據(jù) Last-Modified 標(biāo)頭的值設(shè)置其值,該標(biāo)頭是與此特定資源的先前響應(yīng)一起發(fā)送的。

如果 If-Modified-Since 標(biāo)頭的值與所請(qǐng)求資源的修改日期匹配,則可以節(jié)省一些帶寬并使用空主體響應(yīng)客戶(hù)端。

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

讓我們仔細(xì)看看完整的例子。

@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>

首先,我們獲取所請(qǐng)求的資源并訪(fǎng)問(wèn)其修改日期。我們將日期轉(zhuǎn)換為自格林威治標(biāo)準(zhǔn)時(shí)間1970年1月1日以來(lái)的毫秒數(shù),因?yàn)檫@是Spring框架期望的格式。

然后,我們將日期與 If-Modified-Since 標(biāo)頭的值進(jìn)行比較,并在正匹配上返回一個(gè)空。否則,服務(wù)器發(fā)送具有 Last-Modified 標(biāo)頭的適當(dāng)值的完整響應(yīng)主體。

憑借所有這些知識(shí),您幾乎可以涵蓋所有常見(jiàn)的緩存設(shè)置選項(xiàng)。但是有一個(gè)更重要的機(jī)制你應(yīng)該知道的是......

使用ETag進(jìn)行資源版本控制

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

可以將ETag定義為唯一的字符串值,該值在該時(shí)間點(diǎn)明確地標(biāo)識(shí)資源。 通常,服務(wù)器根據(jù)給定資源的屬性計(jì)算ETag,或者,如果可用,則計(jì)算其最新修改日期。

客戶(hù)端和服務(wù)器之間的通信流程與修改日期檢查的情況幾乎相同。只有標(biāo)題的名稱(chēng)和值不同。

服務(wù)器在名為 ETag 的標(biāo)題中設(shè)置ETag值。當(dāng)客戶(hù)端再次訪(fǎng)問(wèn)資源時(shí),它應(yīng)該在名為 If-None-Match 的頭中發(fā)送其值。如果該值與資源的新計(jì)算的ETag匹配,則服務(wù)器可以使用空內(nèi)容和HTTP代碼304進(jìn)行響應(yīng)。

在Spring中,您可以實(shí)現(xiàn)ETag服務(wù)器流程,如下所示:

@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>

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

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

Last-Modified vs ETag

正如我已經(jīng)提到的, Last-Modified 標(biāo)頭 不太精確, 因?yàn)樗哂幸幻氲木?。為了獲得更高的精度,請(qǐng)選擇 ETag 。

當(dāng)您不跟蹤 資源 的修改日期 時(shí),您也被迫使用 ETag 。服務(wù)器可以根據(jù)資源的屬性計(jì)算其值。將其視為對(duì)象的哈希碼。

如果資源具有其修改日期并且您可以使用一秒精度,請(qǐng)使用 Last-Modified 標(biāo)頭。為什么?因?yàn)?ETag計(jì)算可能是一項(xiàng)昂貴的操作 。

順便提一下,值得一提的是HTTP協(xié)議沒(méi)有指定用于計(jì)算ETag的算法。選擇算法時(shí),您應(yīng)該關(guān)注它的速度。

本文重點(diǎn)介紹緩存GET請(qǐng)求,但您應(yīng)該知道服務(wù)器可以使用 ETag 來(lái)同步更新操作。

Spring ETag過(guò)濾器

因?yàn)镋Tag只是內(nèi)容的字符串表示,所以服務(wù)器可以使用響應(yīng)的字節(jié)表示來(lái)計(jì)算其值。意思是 你可以實(shí)際將ETag分配給任何響應(yīng)。

Spring框架為您提供了ETag響應(yīng)過(guò)濾器實(shí)現(xiàn) ,它可以為您完成。您所要做的就是在應(yīng)用程序中配置過(guò)濾器。

在Spring應(yīng)用程序中添加HTTP過(guò)濾器的最簡(jiǎn)單方法是通過(guò)配置類(lèi)中的 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>

在這種情況下,對(duì) addUrlPatterns() 的調(diào)用是多余的,因?yàn)槟J(rèn)情況下所有路徑都匹配。我把它放在這里證明你可以控制Spring應(yīng)該添加ETag值的資源。

除了ETag生成之外,過(guò)濾器還會(huì)在可能的情況下響應(yīng)HTTP 304和空體內(nèi)容。

但要注意。

ETag計(jì)算可能很昂貴。 對(duì)于某些應(yīng)用程序啟用此過(guò)濾器實(shí)際上可能會(huì)導(dǎo)致弊大于利 。在使用之前考慮一下您的解決方案。

結(jié)論

現(xiàn)在您已了解如何使用HTTP緩存優(yōu)化應(yīng)用程序,哪種方法最適合您,因?yàn)閼?yīng)用程序有不同的需求。

您了解到客戶(hù)端緩存驗(yàn)證是最有效的方法,因?yàn)椴簧婕皵?shù)據(jù)傳輸。在適用時(shí),您應(yīng)該始終支持客戶(hù)端緩存驗(yàn)證。

我們還討論了服務(wù)器端驗(yàn)證并比較了 Last-Modified 和 ETag 標(biāo)頭。最后,您了解了如何在Spring應(yīng)用程序中設(shè)置全局ETag過(guò)濾器。

總結(jié)

以上所述是小編給大家介紹的在Spring Boot中實(shí)現(xiàn)HTTP緩存的方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Java多線(xiàn)程中sleep和wait區(qū)別

    Java多線(xiàn)程中sleep和wait區(qū)別

    本文主要介紹了Java多線(xiàn)程中sleep和wait區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • spring boot整合CAS配置詳解

    spring boot整合CAS配置詳解

    這篇文章主要介紹了spring boot整合CAS配置詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Json讀寫(xiě)本地文件實(shí)現(xiàn)代碼

    Json讀寫(xiě)本地文件實(shí)現(xiàn)代碼

    今天沒(méi)事研究了下Gson,寫(xiě)了個(gè)工具類(lèi),需要的朋友可以參考下
    2014-03-03
  • 使用jd-gui反編譯修改jar包里的.class并重新生成新jar問(wèn)題

    使用jd-gui反編譯修改jar包里的.class并重新生成新jar問(wèn)題

    這篇文章主要介紹了使用jd-gui反編譯修改jar包里的.class并重新生成新jar問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java?流處理之收集器詳解

    Java?流處理之收集器詳解

    這篇文章主要介紹了Java?流處理之收集器,本文以記錄?Record?為例,結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • java中mybatis和hibernate的用法總結(jié)

    java中mybatis和hibernate的用法總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于java中mybatis和hibernate的用法總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-01-01
  • Mybatis動(dòng)態(tài)SQL實(shí)例詳解

    Mybatis動(dòng)態(tài)SQL實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Mybatis動(dòng)態(tài)SQL的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • SptingBoot過(guò)濾器Filter的使用詳解

    SptingBoot過(guò)濾器Filter的使用詳解

    這篇文章主要介紹了SptingBoot過(guò)濾器Filter的使用詳解,Filter屬于Servlet規(guī)范,并不是Spring獨(dú)有的,Filter主要用于攔截請(qǐng)求,做一些業(yè)務(wù)邏輯操作,然后可以決定請(qǐng)求是否可以繼續(xù)往下分發(fā),落到其他的Filter或者對(duì)應(yīng)的Servlet,需要的朋友可以參考下
    2023-09-09
  • Java實(shí)現(xiàn)鼠標(biāo)模擬與鍵盤(pán)映射

    Java實(shí)現(xiàn)鼠標(biāo)模擬與鍵盤(pán)映射

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)鼠標(biāo)模擬與鍵盤(pán)映射,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 基于spring mvc請(qǐng)求controller訪(fǎng)問(wèn)方式

    基于spring mvc請(qǐng)求controller訪(fǎng)問(wèn)方式

    這篇文章主要介紹了spring mvc請(qǐng)求controller訪(fǎng)問(wèn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評(píng)論

临邑县| 噶尔县| 泰兴市| 喀喇| 五原县| 通渭县| 同仁县| 鄂伦春自治旗| 聂拉木县| 冀州市| 长沙县| 汉寿县| 诸城市| 龙岩市| 阿图什市| 冀州市| 竹山县| 湘乡市| 右玉县| 天全县| 扬中市| 瑞金市| 石楼县| 丰顺县| 大安市| 平昌县| 景洪市| 巍山| 驻马店市| 运城市| 固镇县| 临沭县| 万山特区| 汾西县| 镇江市| 阳高县| 建德市| 上高县| 新兴县| 阿拉善右旗| 岗巴县|