Proljetno zahtjevno mapiranje

1. Pregled

U ovom uputstvu usredotočit ćemo se na jednu od glavnih bilješki u Proljetni MVC: @RequestMapping.

Jednostavno rečeno, napomena se koristi za mapiranje web zahtjeva na metode Spring Controller.

2. @Zahtjev za mapiranje Osnove

Počnimo s jednostavnim primjerom: mapiranje HTTP zahtjeva na metodu pomoću nekih osnovnih kriterija.

2.1. @RequestMapping - putem Put

@RequestMapping (value = "/ ex / foos", method = RequestMethod.GET) @ResponseBody public String getFoosBySimplePath () {return "Get some Foos"; }

Isprobati ovo mapiranje jednostavnim kovrča naredba, pokrenite:

curl -i // localhost: 8080 / spring-rest / ex / foos

2.2. @RequestMapping - HTTP metoda

HTTP metoda parametar ima nema zadane vrijednosti. Dakle, ako ne odredimo vrijednost, ona će se preslikati na bilo koji HTTP zahtjev.

Evo jednostavnog primjera, sličnog prethodnom, ali ovaj put preslikanog na HTTP POST zahtjev:

@RequestMapping (value = "/ ex / foos", method = POST) @ResponseBody javni niz postFoos () {return "Objavi nekoliko Foos"; }

Da biste testirali POST putem a kovrča naredba:

curl -i -X ​​POST // localhost: 8080 / spring-rest / ex / foos

3. Zahtjev za mapiranje i HTTP zaglavlja

3.1. @RequestMapping Uz zaglavlja Atribut

Mapiranje se može dodatno suziti specificiranjem zaglavlja za zahtjev:

@RequestMapping (value = "/ ex / foos", headers = "key = val", method = GET) @ResponseBody public String getFoosWithHeader () {return "Nabavite Foos sa zaglavljem"; }

Da bismo testirali operaciju, upotrijebit ćemo kovrča podrška za zaglavlje:

curl -i -H "key: val" // localhost: 8080 / spring-rest / ex / foos

pa čak i više zaglavlja putem zaglavlja atribut @RequestMapping:

@RequestMapping (value = "/ ex / foos", headers = {"key1 = val1", "key2 = val2"}, method = GET) @ResponseBody public String getFoosWithHeaders () {return "Nabavite Foos sa zaglavljem"; }

To možemo testirati naredbom:

curl -i -H "key1: val1" -H "key2: val2" // localhost: 8080 / spring-rest / ex / foos

Imajte na umu da za kovrča sintaksa, dvotačka razdvaja ključ zaglavlja i vrijednost zaglavlja, isto kao u HTTP specifikaciji, dok se u proljeće koristi znak jednakosti.

3.2. @RequestMapping Potroši i proizvodi

Mapiranje vrste medija koje proizvodi kontroler metoda vrijedna je posebne pažnje.

Zahtjev možemo mapirati na temelju njegovog Prihvatiti zaglavlje putem @RequestMappingzaglavlja atribut predstavljen gore:

@RequestMapping (value = "/ ex / foos", method = GET, headers = "Accept = application / json") @ResponseBody public String getFoosAsJsonFromBrowser () {return "Nabavite nekoliko Foos-a sa zaglavljem starim"; }

Podudaranje za ovaj način definiranja Prihvatiti zaglavlje je fleksibilno - koristi sadrži umjesto jednako, pa bi se zahtjev kao što je sljedeći i dalje pravilno mapirao:

curl -H "Prihvaćam: application / json, text / html" // localhost: 8080 / spring-rest / ex / foos

Počevši od proljeća 3.1, @RequestMapping napomena sada ima proizvodi i troši atributi, posebno u tu svrhu:

@RequestMapping (value = "/ ex / foos", method = RequestMethod.GET, produce = "application / json") @ResponseBody public String getFoosAsJsonFromREST () {return "Nabavite Foos sa zaglavljem Novo"; }

Također, stari tip mapiranja s zaglavlja atribut automatski će se pretvoriti u novi proizvodi mehanizam koji počinje s Spring 3.1, pa će rezultati biti identični.

Ovo se troši putem kovrča na isti način:

curl -H "Prihvaćam: application / json" // localhost: 8080 / spring-rest / ex / foos

Dodatno, proizvodi podržava i više vrijednosti:

@RequestMapping (value = "/ ex / foos", method = GET, proizvodi = {"application / json", "application / xml"})

Imajte na umu da su to - stari i novi načini specificiranja Prihvatiti zaglavlje - u osnovi su ista mapiranja, tako da ih Spring neće dopustiti zajedno.

Ako su obje ove metode aktivne, rezultiralo bi:

Uzrok: java.lang.IllegalStateException: Pronađeno je dvosmisleno mapiranje. Ne može se mapirati metoda graha 'fooController' java.lang.String org.baeldung.spring.web.controller .FooController.getFoosAsJsonFromREST () u {[/ ex / foos], methods = [GET], params = [], headers = [ ], troši = [], proizvodi = [application / json], custom = []}: Već postoji preslikana metoda graha 'fooController' java.lang.String org.baeldung.spring.web.controller .FooController.getFoosAsJsonFromBrowser () preslikana .

Završna napomena o novom proizvodi i troši mehanizmi koji se ponašaju drugačije od većine ostalih bilješki: Kada su navedeni na razini tipa, napomene na razini metode ne dopunjuju, već poništavaju informacije na razini tipa.

I naravno, ako želite dublje zakopati u izgradnju REST API-ja s Springom, pogledajte novi tečaj REST s proljećem.

4. Zahtjev za mapiranje S varijablama puta

Dijelovi URI-ja za mapiranje mogu se povezati s varijablama putem @PathVariable bilješka.

4.1. Singl @PathVariable

Jednostavan primjer s jednom varijablom puta:

@RequestMapping (value = "/ ex / foos / {id}", method = GET) @ResponseBody javni niz getFoosBySimplePathWithPathVariable (@PathVariable ("id") long id) {return "Nabavite određeni Foo sa / ex / foos / { id} ", method = GET) @ResponseBody javni String getFoosBySimplePathWithPathVariable (@PathVariable String id) {return" Nabavite određeni Foo sa2-višestrukim putanjama ">4.2. Višestruko @PathVariable

Složeniji URI možda će trebati preslikati više dijelova URI-ja višestruke vrijednosti:

@RequestMapping (value = "/ ex / foos / {fooid} / bar / {barid}", method = GET) @ResponseBody public String getFoosBySimplePathWithPathVariables (@PathVariable long fooid, @PathVariable long barid) {return "Nabavite određenu traku sa iz Foo-a s3-pathvariable-with-regex ">4.3. @PathVariable S Regexom

Regularni izrazi također se mogu koristiti prilikom mapiranja @PathVariable.

Na primjer, ograničit ćemo mapiranje tako da prihvati samo numeričke vrijednosti za iskaznica:

@RequestMapping (value = "/ ex / bars / {numericId: [\ d] +}", method = GET) @ResponseBody public String getBarsBySimplePathWithPathVariable (@PathVariable long numericId) {return "Nabavite određenu traku withrequest-param">5. Zahtjev za mapiranje S parametrima zahtjeva

@RequestMapping omogućuje jednostavno mapiranje parametara URL-a s @RequestParam bilješka.

Sada mapiramo zahtjev u URI:

// localhost: 8080 / spring-rest / ex / bars? id = 100
@RequestMapping (value = "/ ex / bars", method = GET) @ResponseBody public String getBarBySimplePathWithRequestParam (@RequestParam ("id") long id) {return "Nabavite određenu traku sa / ex / bars", params = "id ", method = GET) @ResponseBody javni niz getBarBySimplePathWithExplicitRequestParam (@RequestParam (" id ") long id) {return" Nabavite određenu traku sa / ex / bars ", params = {" id "," second "}, method = GET) @ResponseBody javni niz getBarBySimplePathWithExplicitRequestParams (@RequestParam ("id") long id) {return "Uska Nabavite određenu traku s kutevima">6. Zahtjev za mapiranje Kutni slučajevi

6.1. @RequestMapping - Više putova preslikanih na istu metodu kontrolera

Iako samac @RequestMapping vrijednost puta obično se koristi za metodu pojedinog kontrolera (samo dobra praksa, a ne čvrsto pravilo), postoje slučajevi u kojima može biti potrebno mapiranje više zahtjeva na istu metodu.

U tom slučaju, the vrijednost atribut @RequestMapping prihvaća više preslikavanja, ne samo jedan:

@RequestMapping (value = {"/ ex / advanced / bars", "/ ex / advanced / foos"}, method = GET) @ResponseBody public String getFoosOrBarsByPath () {return "Advanced - Get some Foos or Bars"; }

Sad oboje kovrča naredbe trebaju pogoditi istu metodu:

curl -i // localhost: 8080 / spring-rest / ex / advanced / foos curl -i // localhost: 8080 / spring-rest / ex / advanced / bars

6.2. @RequestMapping - Više metoda HTTP zahtjeva za istom metodom kontrolera

Na isti način kontrolera može se preslikati više zahtjeva koji koriste različite HTTP glagole:

@RequestMapping (value = "/ ex / foos / multiple", method = {RequestMethod.PUT, RequestMethod.POST}) @ResponseBody public String putAndPostFoos () {return "Napredno - PUT i POST unutar jedne metode"; }

S kovrča, obojica će sada pogoditi istu metodu:

curl -i -X ​​POST // localhost: 8080 / spring-rest / ex / foos / multiple curl -i -X ​​PUT // localhost: 8080 / spring-rest / ex / foos / multiple

6.3. @RequestMapping - rezervni zahtjev za sve zahtjeve

Da biste implementirali jednostavno zamjensko rješenje za sve zahtjeve koji koriste određenu HTTP metodu, na primjer, za GET:

@RequestMapping (value = "*", method = RequestMethod.GET) @ResponseBody public String getFallback () {return "Rezerva za GET zahtjeve"; }

ili čak za sve zahtjeve:

@RequestMapping (value = "*", method = {RequestMethod.GET, RequestMethod.POST ...}) @ResponseBody public String allFallback () {return "Zamjena za sve zahtjeve"; }

6.4. Dvosmislena pogreška mapiranja

Dvosmislena pogreška mapiranja događa se kada Spring procijeni da su dva ili više preslikavanja zahtjeva jednaka za različite metode kontrolera. Mapiranje zahtjeva je isto kada ima istu HTTP metodu, URL, parametre, zaglavlja i vrstu medija.

Na primjer, ovo je dvosmisleno mapiranje:

@GetMapping (value = "foos / duplicate") javni niz duplikat () {return "Duplikat"; } @GetMapping (value = "foos / duplicate") javni niz duplicateEx () {return "Duplikat"; }

Izbačena iznimka obično ima poruke o pogreškama u sljedećim redovima:

Uzrok: java.lang.IllegalStateException: Dvosmisleno mapiranje. Nije moguće mapirati metodu 'fooMappingExamplesController' javnom java.lang.String org.baeldung.web.controller.FooMappingExamplesController.duplicateEx () u {[/ ex / foos / duplicate], methods = [GET]}: Već postoji 'fooMapntroxam metoda javna java.lang.String org.baeldung.web.controller.FooMappingExamplesController.duplicate () preslikana.

Pažljivo čitanje poruke o pogrešci ukazuje na činjenicu da Spring nije u stanju mapirati metodu org.baeldung.web.controller.FooMappingExamplesController.duplicateEx (), jer ima proturječno mapiranje s već mapiranim org.baeldung.web.controller.FooMappingExamplesController.duplicate ().

Isječak koda u nastavku neće rezultirati dvosmislenom pogreškom mapiranja jer obje metode vraćaju različite vrste sadržaja:

@GetMapping (value = "foos / duplicate", produce = MediaType.APPLICATION_XML_VALUE) public String duplicateXml () {return "Duplikat"; } @GetMapping (value = "foos / duplicate", produce = MediaType.APPLICATION_JSON_VALUE) public String duplicateJson () {return "{\" message \ ": \" Duplicate \ "}"; }

Ova diferencijacija omogućuje našem upravljaču da vrati točan prikaz podataka na temelju Prihvaća zaglavlje priloženo u zahtjevu.

Drugi način da se to riješi je ažuriranje URL-a dodijeljenog bilo kojoj od dvije uključene metode.

7. Novi prečaci za mapiranje zahtjeva

Spring Framework 4.3 predstavio je nekoliko novih napomena o mapiranju HTTP-a, koje se temelje na @RequestMapping :

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

Te nove bilješke mogu poboljšati čitljivost i smanjiti opširnost koda.

Pogledajmo ove nove bilješke na djelu stvaranjem RESTful API-ja koji podržava CRUD operacije:

@GetMapping ("/ {id}") javni ResponseEntity getBazz (@PathVariable String id) {return new ResponseEntity (novi Bazz (id, "Bazz" + id), HttpStatus.OK); } @PostMapping javni ResponseEntity newBazz (@RequestParam ("name") Naziv niza) {return new ResponseEntity (novi Bazz ("5", ime), HttpStatus.OK); } @PutMapping ("/ {id}") javni ResponseEntity updateBazz (@PathVariable String id, @RequestParam ("name") Naziv niza) {return new ResponseEntity (novi Bazz (id, ime), HttpStatus.OK); } @DeleteMapping ("/ {id}") javni ResponseEntity deleteBazz (@PathVariable String id) {return new ResponseEntity (novi Bazz (id), HttpStatus.OK); }

Ovdje možete duboko zaroniti.

8. Proljetna konfiguracija

Proljetna MVC konfiguracija je dovoljno jednostavna, s obzirom na to da je naša FooController definiran je u sljedećem paketu:

paket org.baeldung.spring.web.controller; @Controller javna klasa FooController {...}

Jednostavno nam treba @Konfiguracija klase kako bi se omogućila potpuna podrška za MVC i konfiguriralo skeniranje puta klase za kontroler:

@Configuration @EnableWebMvc @ComponentScan ({"org.baeldung.spring.web.controller"}) javna klasa MvcConfig {//}

9. Zaključak

Ovaj se članak usredotočio na @RequestMapping napomena u proljeće, raspravljajući o jednostavnom slučaju korištenja, mapiranju HTTP zaglavlja, povezivanju dijelova URI-ja s @PathVariablei rad s URI parametrima i @RequestParam bilješka.

Ako želite naučiti kako koristiti drugu jezgrovitu napomenu u Spring MVC-u, možete istražiti @ModelAttribute bilješka ovdje.

Cjeloviti kôd iz članka dostupan je na GitHubu.