Vodič za proljetne preusmjeravanja

1. Pregled

Ovaj će se članak usredotočiti na provodeći preusmjeravanje u proljeće i razgovarat će o obrazloženju svake strategije.

2. Zašto preusmjeravanje?

Prvo razmotrimo razlozi zbog kojih ćete možda morati izvršiti preusmjeravanje u proljetnoj aplikaciji.

Mnogo je mogućih primjera i razloga, naravno. Jednostavan bi mogao biti POSTIRANJE podataka obrasca, zaobilaženje problema dvostruke prijave ili jednostavno delegiranje tijeka izvršavanja na drugu metodu kontrolera.

Kratka napomena ovdje je da tipični obrazac Post / Redirect / Get ne rješava na odgovarajući način probleme dvostrukog slanja - problemi poput osvježavanja stranice prije završetka početnog slanja mogu i dalje rezultirati dvostrukim slanjem.

3. Preusmjeravanje s RedirectView

Počnimo s ovim jednostavnim pristupom - i idite ravno na primjer:

@Controller @RequestMapping ("/") javna klasa RedirectController {@GetMapping ("/ redirectWithRedirectView") javni RedirectView redirectWithUsingRedirectView (RedirectAttributes attributes) {attributes.addFlashAttributeWithRadirectViretRithireDattrectIt ("flash") attributes.addAttribute ("atribut", "redirectWithRedirectView"); vrati novi RedirectView ("redirectedUrl"); }}

Iza scene, RedirectView potaknut će a HttpServletResponse.sendRedirect () - koji će izvršiti stvarno preusmjeravanje.

Ovdje primijetite kako ubrizgavamo preusmjeravajuće atribute u metodu - okvir će ovdje napraviti težak posao i omogućiti nam interakciju s tim atributima.

Dodamo atribut modela atribut - koji će biti izloženi kao parametar HTTP upita. Model mora sadržavati samo objekte - obično nizove ili objekte koji se mogu pretvoriti u žice.

Isprobajmo sada naše preusmjeravanje - uz pomoć jednostavnog kovrča naredba:

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

Rezultat će biti:

Pronađen HTTP / 1.1 302 poslužitelj: Apache-Coyote / 1.1 Mjesto: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectView

4. Preusmjeravanje s prefiksom preusmjeravanje:

Prethodni pristup - korištenje RedirectView - je neoptimalan iz nekoliko razloga.

Prvo - sada smo povezani s API-jem Spring jer koristimo RedirectView izravno u našem kodu.

Drugo - sada moramo znati od samog početka, kad provodimo tu operaciju kontrolera - da će rezultat uvijek biti preusmjeravanje - što ne mora uvijek biti slučaj.

Bolja opcija je upotreba prefiksa preusmjeravanje: - naziv pogleda za preusmjeravanje ubrizgava se u kontroler kao i bilo koje drugo ime logičkog pogleda. Upravljač nije ni svjestan da se događa preusmjeravanje.

Evo kako to izgleda:

@Controller @RequestMapping ("/") javna klasa RedirectController {@GetMapping ("/ redirectWithRedirectPrefix") public ModelAndView redirectWithUsingRedirectPrefix (ModelMap model) {model.addAttribute ("attribute", "redirectPithRithReithItPrefix; vrati novi ModelAndView ("preusmjeravanje: / preusmjereniUrl", model); }} 

Kada se ime pogleda vrati s prefiksom preusmjeravanje:the UrlBasedViewResolver (i sve njegove podrazrede) prepoznat će ovo kao poseban pokazatelj da se mora dogoditi preusmjeravanje. Ostatak naziva vlasničkog pregleda koristit će se kao URL za preusmjeravanje.

Brza, ali važna napomena ovdje je da - kada ovdje koristimo ovo logično ime pogleda - preusmjeravanje: / preusmjereniUrl - radimo preusmjeravanje u odnosu na trenutni kontekst Servleta.

Možemo se poslužiti imenom kao što je preusmjeravanje: // localhost: 8080 / spring-redirect-and-forward / redirectedUrl ako trebamo preusmjeriti na apsolutni URL.

Dakle, sada, kada izvršimo kovrča naredba:

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

Odmah ćemo biti preusmjereni:

Pronađeni HTTP / 1.1 302 poslužitelj: Apache-Coyote / 1.1 Mjesto: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectPrefix

5. Naprijed s prefiksom naprijed:

Pogledajmo sada kako napraviti nešto malo drugačije - naprijed.

Prije koda, krenimo brzi pregled semantike prosljeđivanja u odnosu na preusmjeravanje na visokoj razini:

  • preusmjeriti će odgovoriti s 302 i novim URL-om u Mjesto Zaglavlje; preglednik / klijent tada će uputiti novi zahtjev za novi URL
  • naprijed događa se u potpunosti na strani poslužitelja; spremnik Servlet prosljeđuje isti zahtjev ciljanom URL-u; URL se neće promijeniti u pregledniku

Pogledajmo sada kod:

@Controller @RequestMapping ("/") javna klasa RedirectController {@GetMapping ("/ forwardWithForwardPrefix") public ModelAndView redirectWithUsingForwardPrefix (ModelMap model) {model.addAttribute ("attribute", "forwardWithForwardPrefix"); vrati novi ModelAndView ("naprijed: / preusmjereniUrl", model); }} 

Isto kao preusmjeravanje:, naprijed: prefiks riješit će UrlBasedViewResolver i njegove podrazrede. Interno će ovo stvoriti InternalResourceView što čini a RequestDispatcher.forward () novom pogledu.

Kad izvršimo naredbu s kovrča:

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

Dobit ćemo HTTP 405 (metoda nije dopuštena):

HTTP / 1.1 405 metoda nije dopuštena Poslužitelj: Apache-Coyote / 1.1 Dozvoli: GET Sadržaj: tekst / html; charset = utf-8

Da zaključimo, u usporedbi s dva zahtjeva koja smo imali u slučaju rješenja za preusmjeravanje, u ovom slučaju imamo samo jedan zahtjev koji izlazi iz preglednika / klijenta na poslužiteljsku stranu. Atribut koji je prethodno dodan preusmjeravanjem, naravno, također nedostaje.

6. Atributi s RedirectAttributes

Dalje - pogledajmo izbliza prosljeđivanje atributa u preusmjeravanju - potpuno iskorištavanje okvira s Preusmjeri atribure:

@GetMapping ("/ redirectWithRedirectAttributes") javni RedirectView redirectWithRedirectAttributes (RedirectAttributes atributi) {attributes.addFlashAttribute ("flashAttribute", "redirectWithRedirectAttributes"); attributes.addAttribute ("atribut", "redirectWithRedirectAttributes"); vrati novi RedirectView ("redirectedUrl"); } 

Kao što smo vidjeli ranije, u metodu možemo izravno ubrizgati objekt atributa - što ovaj mehanizam čini vrlo jednostavnim za upotrebu.

Primijetite i to dodajemo i atribut flash - ovo je atribut koji neće ući u URL. Ono što možemo postići s ovom vrstom atributa je - kasnije možemo pristupiti flash atributu pomoću @ModelAttribute (“flashAttribute”)samo u metodi koja je konačni cilj preusmjeravanja:

@GetMapping ("/ redirectedUrl") javno preusmjeravanje ModelAndView (model ModelMap, @ModelAttribute ("flashAttribute") Objekt flashAttribute) {model.addAttribute ("redirectionAttribute", flashAttribute); vratiti novi ModelAndView ("preusmjeravanje", model); } 

Dakle, za kraj - ako testiramo funkcionalnost pomoću kovrča:

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

Bit ćemo preusmjereni na novo mjesto:

HTTP / 1.1 302 Pronađeni poslužitelj: Apache-Coyote / 1.1 Set-Cookie: JSESSIONID = 4B70D8FADA2FD6C22E73312C2B57E381; Put = / proljetni odmor /; HttpOnly Mjesto: // localhost: 8080 / spring-rest / redirectedUrl; jsessionid = 4B70D8FADA2FD6C22E73312C2B57E381? attribute = redirectWithRedirectAttributes

Na taj način, koristeći Preusmjeri atribure umjesto a ModelMap daje nam sposobnost samo dijeljenja neki atributi između dviju metoda koji su uključeni u operaciju preusmjeravanja.

7. Alternativna konfiguracija bez prefiksa

Istražimo sada alternativnu konfiguraciju - preusmjeravanje bez upotrebe prefiksa.

Da bismo to postigli, moramo koristiti org.springframework.web.servlet.view.XmlViewResolver:

  /WEB-INF/spring-views.xml 

Umjesto org.springframework.web.servlet.view.InternalResourceViewResolver koristili smo u prethodnoj konfiguraciji:

Također moramo definirati a RedirectView grah u konfiguraciji:

Sad možemo pokrenuti preusmjeravanje referenciranjem ovog novog graha prema id:

@Controller @RequestMapping ("/") javna klasa RedirectController {@GetMapping ("/ redirectWithXMLConfig") public ModelAndView redirectWithUsingXMLConfig (ModelMap model) {model.addAttribute ("atribut", "redirectfigXMLC; vrati novi ModelAndView ("RedirectedUrl", model); }} 

A da bismo ga testirali, opet ćemo koristiti kovrča naredba:

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

Rezultat će biti:

Pronađeni HTTP / 1.1 302 poslužitelj: Apache-Coyote / 1.1 Mjesto: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectView

8. Preusmjeravanje HTTP POST zahtjeva

Za slučajeve korištenja poput bankovnih plaćanja, možda ćemo morati preusmjeriti HTTP POST zahtjev. Ovisno o vraćenom HTTP statusnom kodu, POST zahtjev može se preusmjeriti na HTTP GET ili POST.

Prema referenci protokola HTTP 1.1, statusni kodovi 301 (Premješteno trajno) i 302 (Pronađeno) omogućuju promjenu metode zahtjeva iz POST u GET. Specifikacija također definira odgovarajuće statusne kodove 307 (privremena preusmjeravanja) i 308 (trajna preusmjeravanja) koji ne dopuštaju promjenu metode zahtjeva iz POST u GET.

Pogledajmo sada kod za preusmjeravanje zahtjeva za post na drugi zahtjev za post:

@PostMapping ("/ redirectPostToPost") javni ModelAndView redirectPostToPost (HttpServletRequest zahtjev) {request.setAttribute (View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT); vrati novi ModelAndView ("preusmjeravanje: / preusmjerenoPostToPost"); }
@PostMapping ("/ redirectedPostToPost") public ModelAndView redirectedPostToPost () {return new ModelAndView ("redirection"); }

Ajmo sada testirati preusmjeravanje POST-a pomoću kovrča naredba:

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

Preusmjeravamo se na određeno mjesto:

> 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 < Kodiranje prijenosa: komadano <Datum: utorak, 8. kolovoza 2017. 07:33:00 GMT {"id": 1, "content": "preusmjeravanje dovršeno"}

9. Zaključak

Ovaj članak ilustriran tri različita pristupa provedbi preusmjeravanja na proljeće, kako rukovati / prosljeđivati ​​atribute prilikom obavljanja ovih preusmjeravanja, kao i kako rukovati preusmjeravanjima HTTP POST zahtjeva.