En guide til foråret omdirigeringer

1. Oversigt

Denne artikel vil fokusere på implementering af en omdirigering om foråret og vil diskutere ræsonnementet bag hver strategi.

2. Hvorfor foretager en omdirigering?

Lad os først overveje grundene til, at du muligvis skal foretage en omdirigering i en Spring-ansøgning.

Der er selvfølgelig mange mulige eksempler og grunde. En simpel kan være POSTing af formulardata, omgå det dobbelte indsendelsesproblem eller bare delegere eksekveringsstrømmen til en anden controller-metode.

En hurtig sidebemærkning her er, at det typiske Post / Redirect / Get-mønster ikke adresserer problemer med dobbelt indsendelse - problemer som f.eks. At opdatere siden, før den første indsendelse er afsluttet, stadig kan resultere i en dobbelt indsendelse.

3. Omdiriger med RedirectView

Lad os starte med denne enkle tilgang - og gå direkte til et eksempel:

@Controller @RequestMapping ("/") offentlig klasse RedirectController {@GetMapping ("/ redirectWithRedirectView") offentlig RedirectView redirectWithUsingRedirectView (RedirectAttribut attributter) {attributter.addFlashAttribute ("flashAttribute", "redirectWithRedirectView) attributter.addAttribute ("attribut", "redirectWithRedirectView"); returner ny RedirectView ("redirectedUrl"); }}

Bag scenen, RedirectView vil udløse en HttpServletResponse.sendRedirect () - som udfører den faktiske omdirigering.

Bemærk her hvordan vi injicerer omdirigeringsattributterne i metoden - rammen vil gøre det tunge løft her og give os mulighed for at interagere med disse attributter.

Vi tilføjer modelattributten attribut - som vil blive eksponeret som HTTP-forespørgselsparameter. Modellen må kun indeholde objekter - generelt strenge eller objekter, der kan konverteres til strenge.

Lad os nu teste vores omdirigering - ved hjælp af en simpel krølle kommando:

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

Resultatet bliver:

HTTP / 1.1 302 Fundet server: Apache-Coyote / 1.1 Placering: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectView

4. Omdiriger med præfikset omdirigere:

Den tidligere tilgang - ved hjælp af RedirectView - er suboptimalt af nogle få grunde.

Først - vi er nu koblet til Spring API, fordi vi bruger RedirectView direkte i vores kode.

For det andet - vi skal nu vide fra starten, når vi implementerer denne controlleroperation - at resultatet altid vil være en omdirigering - hvilket måske ikke altid er tilfældet.

En bedre mulighed er at bruge præfikset omdirigere: - navnet på omdirigeringsvisningen indsprøjtes i controlleren som ethvert andet logisk visningsnavn. Controlleren er ikke engang klar over, at omdirigering sker.

Sådan ser det ud:

@Controller @RequestMapping ("/") offentlig klasse RedirectController {@GetMapping ("/ redirectWithRedirectPrefix") offentlig ModelAndView redirectWithUsingRedirectPrefix (ModelMap model) {model.addAttribute ("attribut", "redirectWithRedirectPrefix"); returner ny ModelAndView ("redirect: / redirectedUrl", model); }} 

Når et visningsnavn returneres med præfikset omdirigere:det UrlBasedViewResolver (og alle dens underklasser) vil genkende dette som en speciel indikation på, at en omdirigering skal ske. Resten af ​​visningsnavnet bruges som omdirigerings-URL.

En hurtig men vigtig note her er, at - når vi bruger dette logiske visningsnavn her - omdirigering: / redirectedUrl - vi foretager en omdirigering i forhold til den aktuelle Servlet-kontekst.

Vi kan bruge et navn som f.eks en omdirigering: // localhost: 8080 / spring-redirect-and-forward / redirectedUrl hvis vi har brug for at omdirigere til en absolut URL.

Så nu, når vi udfører krølle kommando:

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

Vi omdirigeres straks:

HTTP / 1.1 302 Fundet Server: Apache-Coyote / 1.1 Lokation: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectPrefix

5. Videresend med præfikset frem:

Lad os nu se, hvordan man gør noget lidt anderledes - en fremad.

Lad os gå over før koden en hurtig oversigt på højt niveau af semantikken for fremad vs. omdirigering:

  • omdirigere vil svare med en 302 og den nye URL i Beliggenhed header; browseren / klienten fremsætter derefter en ny anmodning til den nye URL
  • frem sker udelukkende på en serverside; Servlet-containeren videresender den samme anmodning til mål-URL; URL'en ændres ikke i browseren

Lad os nu se på koden:

@Controller @RequestMapping ("/") public class RedirectController {@GetMapping ("/ forwardWithForwardPrefix") public ModelAndView redirectWithUsingForwardPrefix (ModelMap model) {model.addAttribute ("attribute", "forwardWithForwardPrefix"); returner ny ModelAndView ("forward: / redirectedUrl", model); }} 

Samme som omdirigere:, det frem: præfikset løses af UrlBasedViewResolver og dens underklasser. Internt vil dette skabe en InternalResourceView der gør en RequestDispatcher.forward () til den nye visning.

Når vi udfører kommandoen med krølle:

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

Vi får HTTP 405 (Metoden er ikke tilladt):

HTTP / 1.1 405 Metode ikke tilladt Server: Apache-Coyote / 1.1 Tillad: GET Indholdstype: tekst / html; charset = utf-8

For at afslutte, sammenlignet med de to anmodninger, vi havde i tilfælde af omdirigeringsløsningen, har vi i dette tilfælde kun en enkelt anmodning, der går ud fra browseren / klienten til serversiden. Attributten, der tidligere blev tilføjet af omdirigering, mangler naturligvis også.

6. Attributter med RedirectAttributter

Næste - lad os se nærmere på videregivende attributter i en omdirigering - udnytte rammerne fuldt ud med Omdirigeringsattributter:

@GetMapping ("/ redirectWithRedirectAttributter") offentlig RedirectView redirectWithRedirectAttributter (RedirectAttribut attributter) {attributter.addFlashAttribute ("flashAttribute", "redirectWithRedirectAttributter"); attributter.addAttribute ("attribut", "redirectWithRedirectAttributter"); returner ny RedirectView ("redirectedUrl"); } 

Som vi så før, kan vi indsprøjte attributtegnet i metoden direkte - hvilket gør denne mekanisme meget let at bruge.

Bemærk også det vi tilføjer også en flashattribut - dette er en attribut, der ikke kommer ind i URL'en. Hvad vi kan opnå med denne type attribut er - vi kan senere få adgang til flashattributten ved hjælp af @ModelAttribute (“flashAttribute”)kun i den metode, der er det sidste mål for omdirigering:

@GetMapping ("/ redirectedUrl") offentlig ModelAndView omdirigering (ModelMap model, @ModelAttribute ("flashAttribute") Objekt flashAttribute) {model.addAttribute ("redirectionAttribute", flashAttribute); returner ny ModelAndView ("omdirigering", model); } 

Så for at afslutte - hvis vi tester funktionaliteten med krølle:

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

Vi omdirigeres til den nye placering:

HTTP / 1.1 302 fundet server: Apache-coyote / 1.1 sæt-cookie: JSESSIONID = 4B70D8FADA2FD6C22E73312C2B57E381; Sti = / fjederhvile /; HttpOnly Location: // localhost: 8080 / spring-rest / redirectedUrl; jsessionid = 4B70D8FADA2FD6C22E73312C2B57E381? attribut = redirectWithRedirectAttributter

På den måde ved hjælp af Omdirigeringsattributter i stedet for en ModelMap giver os kun evnen til at dele nogle attributter mellem de to metoder der er involveret i omdirigeringsoperationen.

7. En alternativ konfiguration uden præfikset

Lad os nu undersøge en alternativ konfiguration - en omdirigering uden at bruge præfikset.

For at opnå dette er vi nødt til at bruge en org.springframework.web.servlet.view.XmlViewResolver:

  /WEB-INF/spring-views.xml 

I stedet for org.springframework.web.servlet.view.InternalResourceViewResolver vi brugte i den tidligere konfiguration:

Vi skal også definere en RedirectView bønne i konfigurationen:

Nu kan vi udløse omdirigering ved at henvise til denne nye bønne efter id:

@Controller @RequestMapping ("/") public class RedirectController {@GetMapping ("/ redirectWithXMLConfig") public ModelAndView redirectWithUsingXMLConfig (ModelMap model) {model.addAttribute ("attribute", "redirectWithXMLConfig"); returner ny ModelAndView ("RedirectedUrl", model); }} 

Og for at teste det, bruger vi igen krølle kommando:

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

Resultatet bliver:

HTTP / 1.1 302 fundet server: Apache-Coyote / 1.1 placering: // localhost: 8080 / spring-rest / redirectedUrl? Attribute = redirectWithRedirectView

8. Omdirigering af en HTTP POST-anmodning

For brugssager som bankbetalinger skal vi muligvis omdirigere en HTTP POST-anmodning. Afhængigt af den returnerede HTTP-statuskode kan POST-anmodning omdirigeres til en HTTP GET eller POST.

I henhold til HTTP 1.1-protokolreference tillader statuskoder 301 (flyttet permanent) og 302 (fundet) anmodningsmetoden at blive ændret fra POST til GET. Specifikationen definerer også de tilsvarende statuskoder 307 (Midlertidig omdirigering) og 308 (Permanent omdirigering), der ikke tillader, at anmodningsmetoden ændres fra POST til GET.

Lad os nu se på koden til omdirigering af en postanmodning til en anden postanmodning:

@PostMapping ("/ redirectPostToPost") offentlig ModelAndView redirectPostToPost (HttpServletRequest anmodning) {request.setAttribute (Vis.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT); returner ny ModelAndView ("redirect: / redirectedPostToPost"); }
@PostMapping ("/ redirectedPostToPost") offentlig ModelAndView omdirigeretPostToPost () {returner ny ModelAndView ("omdirigering"); }

Lad os nu teste omdirigering af POST ved hjælp af krølle kommando:

krølle -L --verbose -X POST // localhost: 8080 / spring-rest / redirectPostToPost

Vi bliver omdirigeret til det bestemt sted:

> POST / omdirigeretPostToPost HTTP / 1.1> Host: localhost: 8080> User-Agent: curl / 7.49.0> Accept: * / *> <HTTP / 1.1 200 <Content-Type: application / json; charset = UTF-8 < Overførselskodning: klumpet <Dato: Tirsdag, 8. august 2017 07:33:00 GMT {"id": 1, "content": "omdirigering afsluttet"}

9. Konklusion

Denne artikel er illustreret tre forskellige tilgange til implementering af en omdirigering i foråret, hvordan man håndterer / videregiver attributter, når man foretager disse omdirigeringer, samt hvordan man håndterer omdirigeringer af HTTP POST-anmodninger.


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