Sprievodca jarnými presmerovaniami

1. Prehľad

Tento článok sa zameria na implementácia presmerovania na jar a bude diskutovať o dôvodoch každej stratégie.

2. Prečo presmerovanie?

Poďme sa najskôr zamyslieť dôvody, prečo bude pravdepodobne potrebné vykonať presmerovanie v jarnej aplikácii.

Existuje samozrejme veľa možných príkladov a dôvodov. Jedným jednoduchým môže byť POSTing údajov formulára, riešenie problému s dvojitým odoslaním alebo iba delegovanie toku vykonávania na inú metódu radiča.

Krátka poznámka je, že typický vzor Post / Redirect / Get adekvátne nerieši problémy s dvojitým odoslaním - problémy ako napríklad obnovenie stránky pred dokončením pôvodného odoslania môžu stále viesť k dvojitému odoslaniu.

3. Presmerujte pomocou RedirectView

Začnime týmto jednoduchým prístupom - a choď rovno k príkladu:

@Controller @RequestMapping ("/") verejná trieda RedirectController {@GetMapping ("/ redirectWithRedirectView") verejná RedirectView redirectWithUsingRedirectView (atribúty RedirectAttributes) {attributes.addFlashAttribute ("flashAttribute", "redirectWithRedirectView"); attributes.addAttribute ("attribute", "redirectWithRedirectView"); vrátiť nový RedirectView ("redirectedUrl"); }}

V zákulisí, RedirectView spustí a HttpServletResponse.sendRedirect () - ktorý vykoná skutočné presmerovanie.

Všimnite si tu ako vkladáme do metódy atribúty presmerovania - rámec tu urobí ťažké práce a umožní nám interakciu s týmito atribútmi.

Pridávame atribút model atribút - ktorý bude vystavený ako parameter dopytu HTTP. Model musí obsahovať iba objekty - zvyčajne reťazce alebo objekty, ktoré je možné previesť na reťazce.

Poďme si teraz otestovať naše presmerovanie - pomocou jednoduchého zvlnenie príkaz:

curl -i // localhost: 8080 / spring-rest / redirectWithRedirectView

Výsledkom bude:

HTTP / 1.1 302 Nájdený server: Apache-Coyote / 1.1 Umiestnenie: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectView

4. Presmerujte pomocou predvoľby presmerovanie:

Predchádzajúci prístup - použitie RedirectView - je neoptimálne z niekoľkých dôvodov.

Najprv - teraz sme pripojení k Spring API, pretože používame RedirectView priamo v našom kóde.

Po druhé - teraz musíme hneď od začiatku vedieť, že pri implementácii tejto činnosti kontrolóra - že výsledkom bude vždy presmerovanie - čo nemusí platiť vždy.

Lepšou možnosťou je použitie predvoľby presmerovanie: - názov presmerovaného pohľadu je vložený do radiča ako každý iný názov logického pohľadu. Ovládač si ani neuvedomuje, že dochádza k presmerovaniu.

Vyzerá to takto:

@Controller @RequestMapping ("/") verejná trieda RedirectController {@GetMapping ("/ redirectWithRedirectPrefix") verejná ModelAndView redirectWithUsingRedirectPrefix (ModelMap model) {model.addAttribute ("atribút", "redirectWithRedirectPrefix"); vrátiť nový ModelAndView ("redirect: / redirectedUrl", model); }} 

Keď sa vráti názov zobrazenia s predponou presmerovanie:the UrlBasedViewResolver (a všetky jeho podtriedy) to rozpozná ako zvláštny znak toho, že je potrebné vykonať presmerovanie. Zvyšok názvu zobrazenia sa použije ako adresa URL presmerovania.

Krátka, ale dôležitá poznámka je, že - keď tu použijeme tento názov logického pohľadu - presmerovanie: / redirectedUrl - robíme presmerovanie vo vzťahu k aktuálnemu kontextu servletu.

Môžeme použiť názov ako napr presmerovanie: // localhost: 8080 / spring-redirect-and-forward / redirectedUrl ak potrebujeme presmerovať na absolútnu adresu URL.

Takže teraz, keď vykonáme príkaz zvlnenie príkaz:

curl -i // localhost: 8080 / spring-rest / redirectWithRedirectPrefix

Ihneď dostaneme presmerovanie:

HTTP / 1.1 302 Nájdený server: Apache-Coyote / 1.1 Umiestnenie: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectPrefix

5. Poslať ďalej s predponou dopredu:

Pozrime sa teraz, ako urobiť niečo trochu iné - dopredu.

Pred kódom poďme na to rýchly prehľad na vysokej úrovni o sémantike forwardu a presmerovania:

  • presmerovanie odpovie 302 a novou adresou URL v Poloha hlavička; prehliadač / klient potom urobí ďalšiu požiadavku na novú adresu URL
  • dopredu deje sa výlučne na strane servera; kontajner servletu preposiela rovnakú požiadavku na cieľovú adresu URL; URL sa v prehliadači nezmení

Teraz sa pozrime na kód:

@Controller @RequestMapping ("/") verejná trieda RedirectController {@GetMapping ("/ forwardWithForwardPrefix") verejná ModelAndView redirectWithUsingForwardPrefix (ModelMap model) {model.addAttribute ("atribút", "forwardWithForwardPrefix"); vrátiť nový ModelAndView ("forward: / redirectedUrl", model); }} 

Rovnaké ako presmerovanie:, dopredu: predpona bude vyriešená UrlBasedViewResolver a jeho podtriedy. Interne to vytvorí InternalResourceView ktorá robí a RequestDispatcher.forward () do nového pohľadu.

Keď vykonáme príkaz pomocou zvlnenie:

zvlnenie -I // localhost: 8080 / spring-rest / forwardWithForwardPrefix 

Dostaneme HTTP 405 (metóda nie je povolená):

Metóda HTTP / 1.1 405 nie je povolená Server: Apache-Coyote / 1.1 Allow: GET Content-Type: text / html; charset = utf-8

Aby sme to zhrnuli, v porovnaní s dvoma požiadavkami, ktoré sme mali v prípade riešenia presmerovania, v tomto prípade máme iba jednu požiadavku smerujúcu z prehliadača / klienta na stranu servera. Atribút, ktorý predtým pridalo presmerovanie, samozrejme tiež chýba.

6. Atribúty pomocou RedirectAttributes

Ďalej - pozrime sa bližšie odovzdávanie atribútov v presmerovaní - plné využitie rámca s RedirectAttribures:

@GetMapping ("/ redirectWithRedirectAttributes") verejné RedirectView redirectWithRedirectAttributes (atribúty RedirectAttributes) {attributes.addFlashAttribute ("flashAttribute", "redirectWithRedirectAttributes"); attributes.addAttribute ("attribute", "redirectWithRedirectAttributes"); vrátiť nový RedirectView ("redirectedUrl"); } 

Ako sme už videli predtým, môžeme vložiť objekt atribútov do metódy priamo - čo robí tento mechanizmus veľmi ľahko použiteľným.

Všimnite si tiež, že pridávame tiež atribút flash - toto je atribút, ktorý sa do adresy URL nedostane. Toho, čo môžeme dosiahnuť pomocou tohto druhu atribútu, je - k atribútu flash môžeme neskôr pristupovať pomocou @ModelAttribute („flashAttribute“)iba v metóde, ktorá je konečným cieľom presmerovania:

@GetMapping ("/ redirectedUrl") verejné presmerovanie ModelAndView (model ModelMap, @ModelAttribute ("flashAttribute") objekt flashAttribute) {model.addAttribute ("redirectionAttribute", flashAttribute); vrátiť nový ModelAndView ("presmerovanie", model); } 

Takže, zabaliť - ak otestujeme funkčnosť s zvlnenie:

curl -i // localhost: 8080 / spring-rest / redirectWithRedirectAttributes

Budeme presmerovaní na nové miesto:

Nájdený server HTTP / 1.1 302: Apache-Coyote / 1.1 Set-Cookie: JSESSIONID = 4B70D8FADA2FD6C22E73312C2B57E381; Cesta = / pružinový odpočinok /; HttpOnly Location: // localhost: 8080 / spring-rest / redirectedUrl; jsessionid = 4B70D8FADA2FD6C22E73312C2B57E381? attribute = redirectWithRedirectAttributes

Týmto spôsobom pomocou RedirectAttribures namiesto a ModelMap nám dáva možnosť iba zdieľať niektoré atribúty medzi týmito dvoma metódami ktoré sa podieľajú na operácii presmerovania.

7. Alternatívna konfigurácia bez predpony

Poďme teraz preskúmať alternatívnu konfiguráciu - presmerovanie bez použitia predpony.

Aby sme to dosiahli, musíme použiť org.springframework.web.servlet.view.XmlViewResolver:

  /WEB-INF/spring-views.xml 

Namiesto org.springframework.web.servlet.view.InternalResourceViewResolver sme použili v predchádzajúcej konfigurácii:

Musíme tiež definovať a RedirectView fazuľa v konfigurácii:

Teraz môžeme spustiť presmerovanie odkazom na tento nový fazuľa podľa id:

@Controller @RequestMapping ("/") verejná trieda RedirectController {@GetMapping ("/ redirectWithXMLConfig") verejná ModelAndView redirectWithUsingXMLConfig (model ModelMap) {model.addAttribute ("atribút", "redirectWithXMLConfig"); vrátiť nový ModelAndView ("RedirectedUrl", model); }} 

A aby sme to otestovali, opäť použijeme zvlnenie príkaz:

curl -i // localhost: 8080 / spring-rest / redirectWithRedirectView

Výsledkom bude:

HTTP / 1.1 302 Nájdený server: Apache-Coyote / 1.1 Umiestnenie: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectView

8. Presmerovanie požiadavky HTTP POST

Pre prípady použitia, ako sú bankové platby, bude možno potrebné presmerovať žiadosť HTTP POST. V závislosti na vrátenom stavovom kóde HTTP môže byť požiadavka POST presmerovaná na HTTP GET alebo POST.

Podľa referencie protokolu HTTP 1.1 umožňujú stavové kódy 301 (Moved Permanently) a 302 (Found) zmenu metódy požiadavky z POST na GET. Špecifikácia tiež definuje zodpovedajúce stavové kódy 307 (Temporary Redirect) a 308 (Permanent Redirect), ktoré neumožňujú zmenu metódy požiadavky z POST na GET.

Teraz sa pozrime na kód na presmerovanie žiadosti o príspevok na inú žiadosť o príspevok:

@PostMapping ("/ redirectPostToPost") verejný ModelAndView redirectPostToPost (požiadavka HttpServletRequest) {request.setAttribute (View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT); vrátiť nový ModelAndView ("redirect: / redirectedPostToPost"); }
@PostMapping ("/ redirectedPostToPost") public ModelAndView redirectedPostToPost () {return new ModelAndView ("redirection"); }

Teraz otestujme presmerovanie POST pomocou zvlnenie príkaz:

curl -L --verbose -X POST // localhost: 8080 / spring-rest / redirectPostToPost

Sme presmerovaní na určené miesto:

> POST / redirectedPostToPost HTTP / 1.1> Host: localhost: 8080> User-Agent: curl / 7.49.0> Accept: * / *> <HTTP / 1.1 200 <Content-Type: application / json; charset = UTF-8 < Kódovanie prenosu: blokované <Dátum: Utorok, 8. augusta 2017 07:33:00 GMT {"id": 1, "content": "presmerovanie dokončené"}

9. Záver

Tento článok je ilustrovaný tri rôzne prístupy k implementácii presmerovania na jar, ako spracovávať / odovzdávať atribúty pri vykonávaní týchto presmerovaní a tiež ako spracovávať presmerovania požiadaviek HTTP POST.


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