Hlavičky vyrovnávacej pamäte na jar MVC

1. Prehľad

V tomto výučbe sa dozvieme niečo o ukladaní do pamäte cache HTTP. Taktiež sa pozrieme na rôzne spôsoby implementácie tohto mechanizmu medzi klientom a aplikáciou Spring MVC.

2. Predstavujeme ukladanie do pamäte cache HTTP

Keď otvoríme webovú stránku v prehliadači, zvyčajne si z webového servera stiahne veľa zdrojov:

Napríklad v tomto príklade musí prehliadač stiahnuť tri zdroje pre jeden /Prihlásiť sa stránke. Je bežné, že prehliadač robí na každú webovú stránku viac požiadaviek HTTP. Ak teraz takéto stránky vyžadujeme veľmi často, spôsobí to veľkú sieťovú premávku a ich zobrazenie bude trvať dlhšie.

Aby sa znížilo zaťaženie siete, protokol HTTP umožňuje prehliadačom ukladať niektoré z týchto zdrojov do medzipamäte. Ak je táto možnosť povolená, môžu prehliadače uložiť kópiu prostriedku do miestnej medzipamäte. Výsledkom je, že prehliadače môžu tieto stránky zobrazovať z miestneho úložiska namiesto toho, aby o ne požiadali v sieti:

Webový server môže nasmerovať prehľadávač do medzipamäte konkrétneho zdroja pridaním a Cache-Control hlavička v odpovedi.

Pretože sa zdroje ukladajú do pamäte cache ako lokálna kópia,existuje riziko poskytovania zastaraného obsahu z prehliadača. Preto webové servery zvyčajne pridávajú čas vypršania platnosti v Cache-Control hlavička.

V nasledujúcich častiach pridáme túto hlavičku do odpovede od radiča Spring MVC. Neskôr uvidíme aj API Spring na overenie prostriedkov v medzipamäti na základe doby vypršania platnosti.

3. Cache-Control v odpovedi kontrolóra

3.1. Použitím ResponseEntity

Najjednoduchší spôsob, ako to dosiahnuť, jePouži CacheControl trieda staviteľov poskytovaná spoločnosťou Spring:

@GetMapping ("/ hello / {name}") @ResponseBody public ResponseEntity ahoj (názov reťazca @PathVariable) {CacheControl cacheControl = CacheControl.maxAge (60, TimeUnit.SECONDS) .noTransform () .mustRevalidate (); return ResponseEntity.ok () .cacheControl (cacheControl) .body ("Hello" + meno); }

Týmto pridáte a Cache-Control hlavička v odpovedi:

@Test void whenHome_thenReturnCacheHeader () throws Exception {this.mockMvc.perform (MockMvcRequestBuilders.get ("/ hello / baeldung")) .andDo (MockMvcResultHandlers.print ()) .andExpect (MockMvcResultMatchers) andExpect (MockMvcResultMatchers.header () .string ("Cache-Control", "max-age = 60, must-revalidate, no-transform")); }

3.2. Použitím HttpServletResponse

Ovládače často musia vrátiť názov pohľadu z metódy obsluhy. AvšakResponseEntity trieda nám neumožňuje vrátiť názov pohľadu a súčasne sa vysporiadať s telom žiadosti.

Alternatívne pre tieto radiče môžeme nastaviť Cache-Control hlavička v HttpServletResponse priamo:

@GetMapping (value = "/ home / {name}") verejný reťazec domov (názov reťazca @PathVariable, konečná odpoveď HttpServletResponse) {response.addHeader ("Cache-Control", "max-age = 60, must-revalidate, nie -transformácia)); vrátiť sa domov"; }

Týmto sa tiež pridá a Cache-Control hlavička v odpovedi HTTP podobná poslednej časti:

@Test void whenHome_thenReturnCacheHeader () throws Exception {this.mockMvc.perform (MockMvcRequestBuilders.get ("/ home / baeldung")) .andDo (MockMvcResultHandlers.print ()) .andExpect (MockMvcRusult )atch) andExpect (MockMvcResultMatchers.header () .string ("Cache-Control", "max-age = 60, must-revalidate, no-transform")) .andExpect (MockMvcResultMatchers.view (). name ("home")); }

4. Cache-Control pre statické zdroje

Naša jarná aplikácia MVC vo všeobecnosti slúži mnohým statickým zdrojom, ako sú súbory HTML, CSS a JS. Pretože takéto súbory spotrebúvajú veľkú šírku pásma siete, je dôležité, aby si ich prehliadače ukladali do medzipamäte. Toto znova povolíme pomocou Cache-Control hlavička v odpovedi.

Jar nám umožňuje kontrolovať toto chovanie cache pri mapovaní zdrojov:

@Override public void addResourceHandlers (konečný register ResourceHandlerRegistry) {registry.addResourceHandler ("/ resources / **"). AddResourceLocations ("/ resources /") .setCacheControl (CacheControl.maxAge (60, TimeUnit.SECONDS) .noTransform (). mustRevalidate ()); }

To zaisťuje, že všetky zdrojedefinované v/ zdroje sa vracajú s a Cache-Control hlavička v odpovedi.

5. Cache-Control v Interceptoroch

V našej jarnej aplikácii MVC môžeme použiť zachytávače na vykonanie predbežného a následného spracovania pre každú požiadavku. Toto je ďalší zástupný symbol, kde môžeme ovládať správanie aplikácie v medzipamäti.

Teraz namiesto implementácie vlastného zachytávača použijeme WebContentInterceptor poskytuje jar:

@Override public void addInterceptors (register InterceptorRegistry) {WebContentInterceptor interceptor = nový WebContentInterceptor (); interceptor.addCacheMapping (CacheControl.maxAge (60, TimeUnit.SECONDS) .noTransform () .mustRevalidate (), "/ login / *"); registry.addInterceptor (interceptor); }

Tu sme zaregistrovali WebContentInterceptor a pridal Cache-Control hlavička podobná posledným častiam. Je pozoruhodné, že môžeme pridať rôzne Cache-Control hlavičky pre rôzne vzory adries URL.

Vo vyššie uvedenom príklade pre všetky žiadosti začínajúce sa /Prihlásiť sa, pridáme túto hlavičku:

@Test void whenInterceptor_thenReturnCacheHeader () vyvolá výnimku {this.mockMvc.perform (MockMvcRequestBuilders.get ("/ login / baeldung")) .andDo (MockMvcResultHandlers.print ()) .andExpect (MockMvcResult) andExpect (MockMvcResultMatchers.header () .string ("Cache-Control", "max-age = 60, must-revalidate, no-transform")); }

6. Validácia medzipamäte na jar MVC

Doteraz sme diskutovali o rôznych spôsoboch zahrnutia a Cache-Control hlavička v odpovedi. To naznačuje, že klienti alebo prehliadače ukladajú prostriedky do medzipamäte na základe konfiguračných vlastností, ako je maximálny vek.

Je to všeobecne dobrý nápad pridať ku každému prostriedku čas skončenia platnosti vyrovnávacej pamäte. Vďaka tomu sa prehliadače môžu vyhnúť tomu, aby z medzipamäte zobrazovali prostriedky, ktorým vypršala platnosť.

Aj keď by prehliadače mali vždy skontrolovať vypršanie platnosti, nemusí byť potrebné zdroj načítať vždy. Ak prehliadač dokáže overiť, že sa prostriedok na serveri nezmenil, môže pokračovať v poskytovaní jeho verzie v pamäti. Z tohto dôvodu nám protokol HTTP poskytuje dve hlavičky odpovedí:

  1. Etag - hlavička odpovede HTTP, ktorá ukladá jedinečnú hodnotu hash, aby sa určilo, či sa zdroj uložený v pamäti zmenil na serveri - zodpovedajúci Ak-Žiadny-Zhoda hlavička požiadavky musí niesť poslednú hodnotu Etag
  2. Naposledy zmenené - hlavička odpovede HTTP, ktorá uchováva jednotku času, kedy bol zdroj naposledy aktualizovaný - zodpovedajúci If-Unmodified-since hlavička požiadavky musí obsahovať dátum poslednej úpravy

Pomocou ktorejkoľvek z týchto hlavičiek môžeme skontrolovať, či je potrebné znovu načítať vypršaný zdroj. Po overení hlavičiekserver môže zdroj znova odoslať alebo odoslať kód 304 HTTP, čo znamená, že nedošlo k žiadnej zmene. V prípade druhého scenára môžu prehliadače naďalej používať prostriedok v medzipamäti.

The Naposledy zmenené hlavička dokáže ukladať iba časové intervaly s presnosťou až na sekundy. Môže to byť obmedzenie v prípadoch, keď sa vyžaduje kratšia doba platnosti. Z tohto dôvodu sa odporúča používať Etag namiesto toho. Odkedy Etag hlavička ukladá hodnotu hash, je možné vytvoriť jedinečný hash až do jemnejších intervalov, ako sú nanosekundy.

Povedzme si teda, čo to vyzerá, ako to vyzerá Naposledy zmenené.

Jar poskytuje niektoré užitočné metódy na kontrolu, či žiadosť obsahuje hlavičku vypršania platnosti alebo nie:

@GetMapping (value = "/ productInfo / {name}") public ResponseEntity validate (@PathVariable názov reťazca, požiadavka WebRequest) {ZoneId zoneId = ZoneId.of ("GMT"); long lastModifiedTimestamp = LocalDateTime.of (2020, 02, 4, 19, 57, 45) .atZone (zoneId) .toInstant (). toEpochMilli (); if (request.checkNotModified (lastModifiedTimestamp)) {return ResponseEntity.status (304) .build (); } return ResponseEntity.ok (). body ("Hello" + meno); }

Jar poskytuje checkNotModified () metóda na kontrolu, či bol zdroj zmenený od poslednej požiadavky:

@Test void whenValidate_thenReturnCacheHeader () vyvolá výnimku {HttpHeaders headers = new HttpHeaders (); headers.add (IF_UNMODIFIED_SINCE, "Utorok, 4. februára 2020 19:57:25 GMT"); this.mockMvc.perform (MockMvcRequestBuilders.get ("/ productInfo / baeldung"). headers (headers)) .andDo (MockMvcResultHandlers.print ()) .andExpect (MockMvcResultMatchers.status (). is (304)); }

7. Záver

V tomto článku sme sa dozvedeli o ukladaní do vyrovnávacej pamäte HTTP pomocou Cache-Control hlavička odpovede na jar MVC. Môžeme buď pridať hlavičku do odpovede radiča pomocou ResponseEntity triedy alebo prostredníctvom mapovania zdrojov pre statické zdroje.

Túto hlavičku môžeme tiež pridať pre konkrétne vzory adries URL pomocou zachytávačov jari.

Ako vždy, kód je k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found