Http pretvarači poruka s Spring Frameworkom

1. Pregled

Ovaj članak opisuje kako konfigurirati HttpMessageConverters u proljeće.

Jednostavno rečeno, možemo koristiti pretvarače poruka za razvrstavanje i uklanjanje oznaka Java objekata u i iz JSON-a, XML-a, itd. - preko HTTP-a.

2. Osnove

2.1. Omogućite web MVC

Za početak web aplikacija mora biti konfigurirano s podrškom za Spring MVC. Prikladan i vrlo prilagodljiv način za to je korištenje @EnableWebMvc napomena:

@EnableWebMvc @Configuration @ComponentScan ({"com.baeldung.web"}) javna klasa WebConfig implementira WebMvcConfigurer {...}

Imajte na umu da se ova klasa provodi WebMvcConfigurer - što će nam omogućiti da zadani popis Http pretvarača promijenimo svojim.

2.2. Zadani pretvarači poruka

Prema zadanim postavkama, sljedeće HttpMessageConverter S instance su unaprijed omogućene:

  • ByteArrayHttpMessageConverter Pretvara bajtovske nizove
  • StringHttpMessageConverter - pretvara žice
  • ResourceHttpMessageConverter - obraća org.springframework.core.io.Resource za bilo koju vrstu oktet struje
  • SourceHttpMessageConverter - obraća javax.xml.transform.Source
  • ObrazacHttpMessageConverter - pretvara podatke obrasca u / iz a MultiValueMap.
  • Jaxb2RootElementHttpMessageConverter - pretvara Java objekte u / iz XML-a (dodaje se samo ako je JAXB2 prisutan na putu predavanja)
  • MappingJackson2HttpMessageConverter - pretvara JSON (dodaje se samo ako je Jackson 2 prisutan na stazi)

  • MappingJacksonHttpMessageConverter - pretvara JSON (dodaje se samo ako je Jackson prisutan na stazi)
  • AtomFeedHttpMessageConverter - pretvara Atom feedove (dodaje se samo ako je Rim prisutan na stazi)
  • RssChannelHttpMessageConverter Pretvara RSS izvore (dodaje se samo ako je Rim prisutan na stazi)

3. Komunikacija klijent-poslužitelj - samo JSON

3.1. Pregovaranje o sadržaju na visokoj razini

Svaki HttpMessageConverter implementacija ima jedan ili nekoliko povezanih MIME tipova.

Kada primate novi zahtjev, Proljeće će koristiti "Prihvatiti”Zaglavlje za određivanje vrste medija na koju treba odgovoriti.

Tada će pokušati pronaći registrirani pretvarač koji je sposoban rukovati tom određenom vrstom medija. Konačno, to će upotrijebiti za pretvaranje entiteta i povratni odgovor.

Postupak je sličan primanju zahtjeva koji sadrži JSON informacije. Okvir će koristiti "Vrsta sadržaja”Zaglavlje za određivanje vrste medija tijela zahtjeva.

Zatim će tražiti HttpMessageConverter koji može pretvoriti tijelo koje je klijent poslao u Java objekt.

Pojasnimo to na brzom primjeru:

  • klijent šalje GET zahtjev na / foos s Prihvatiti zaglavlje postavljeno na aplikacija / json - dobiti sve Foo resurse kao JSON
  • the Foo Pritisnut je Spring Controller i vraća odgovarajući Foo Java entiteti
  • Spring zatim koristi jedan od pretvarača poruka Jacksona za marširanje entiteta u JSON

Pogledajmo sada specifičnosti kako to funkcionira - i kako možemo iskoristiti @ResponseBody i @RequestBody bilješke.

3.2. @ResponseBody

@ResponseBody on Controller metoda ukazuje Springu da povratna vrijednost metode serializira se izravno u tijelo HTTP odgovora. Kao što je gore spomenuto, „Prihvatiti”Zaglavlje koje je odredio Klijent koristit će se za odabir odgovarajućeg Http pretvarača za marširanje entiteta.

Pogledajmo jednostavan primjer:

@GetMapping ("/ {id}") public @ResponseBody Foo findById (@PathVariable long id) {return fooService.findById (id); }

Sada će klijent odrediti zaglavlje "Prihvati" na aplikacija / json u zahtjevu - primjer kovrča naredba:

curl --header "Accept: application / json" // localhost: 8080 / spring-boot-rest / foos / 1

The Foo razred:

javna klasa Foo {private long id; privatni naziv niza; }

I Http tijelo za odgovor:

{"id": 1, "name": "Paul",}

3.3. @RequestBody

Možemo koristiti @RequestBody napomena na argumentu metode Controller da bi se naznačilo da je tijelo HTTP zahtjeva deserializirano za taj određeni entitet Java. Da bi odredio odgovarajući pretvarač, Spring će upotrijebiti zaglavlje "Content-Type" iz zahtjeva klijenta.

Pogledajmo primjer:

@PutMapping ("/ {id}") javno ažuriranje @ResponseBody void (@RequestBody Foo foo, @PathVariable String id) {fooService.update (foo); }

Dalje, konzumirajmo ovo s JSON objektom - mi određujemo “Content-Type biti aplikacija / json:

curl -i -X ​​PUT -H "Content-Type: application / json" -d '{"id": "83", "name": "klik"}' // localhost: 8080 / spring-boot-rest / foos / 1

Vraćamo 200 OK - uspješan odgovor:

HTTP / 1.1 200 OK poslužitelj: Apache-Coyote / 1.1 Duljina sadržaja: 0 Datum: Fri, 10. siječnja 2014. 11:18:54 GMT

4. Konfiguracija prilagođenih pretvarača

Možemo i mi prilagodite pretvarače poruka primjenom WebMvcConfigurer sučelje i nadjačavanje configureMessageConverters metoda:

@EnableWebMvc @Configuration @ComponentScan ({"com.baeldung.web"}) javna klasa WebConfig implementira WebMvcConfigurer {@Override public void configureMessageConverters (Popis pretvarači) {messageConverters.add (createXmlHttpMessageConverter ()); messageConverters.add (novo MappingJackson2HttpMessageConverter ()); } privatni HttpMessageConverter createXmlHttpMessageConverter () {MarshallingHttpMessageConverter xmlConverter = novi MarshallingHttpMessageConverter (); XStreamMarshaller xstreamMarshaller = novi XStreamMarshaller (); xmlConverter.setMarshaller (xstreamMarshaller); xmlConverter.setUnmarshaller (xstreamMarshaller); vrati xmlConverter; }}

U ovom primjeru stvaramo novi pretvarač - MarshallingHttpMessageConverter - i pomoću Spring XStream podrške za njegovo konfiguriranje. To omogućuje veliku fleksibilnost od radimo s API-ima niske razine temeljnog okvira za raspodjelu - u ovom slučaju XStream - i to možemo konfigurirati kako god želimo.

Imajte na umu da ovaj primjer zahtijeva dodavanje XStream knjižnice u put predavanja.

Također imajte na umu da proširenjem ove klase podrške, gubimo zadane pretvarače poruka koji su prethodno bili unaprijed registrirani.

To naravno sada možemo učiniti i za Jacksona - definiranjem vlastitog MappingJackson2HttpMessageConverter. Sada možemo postaviti običaj ObjectMapper na ovom pretvaraču i neka bude konfiguriran prema potrebi.

U ovom je slučaju XStream odabrana implementacija maršalera / unmaršalera, ali drugi vole CastorMarshaller može se koristiti i.

U ovom trenutku - s omogućenim XML-om na stražnjoj strani - možemo konzumirati API s XML prikazima:

curl --header "Accept: application / xml" // localhost: 8080 / spring-boot-rest / foos / 1

4.1. Podrška za proljetno podizanje sustava

Ako koristimo Spring Boot, možemo izbjeći implementaciju WebMvcConfigurer i ručno dodavanje svih pretvarača poruka kao što smo to učinili gore.

Možemo samo definirati drugačije HttpMessageConverter grah u kontekstu, a Spring Boot će ih automatski dodati u autokonfiguraciju koju kreira:

@Bean public HttpMessageConverter createXmlHttpMessageConverter () {MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter (); // ... return xmlConverter; }

5. Korištenje Spring-a RestTemplate S Http pretvaračima poruka

Kao i na strani poslužitelja, Http pretvorba poruka može se konfigurirati i na klijentskoj strani na Springu RestTemplate.

Konfigurirat ćemo predložak s "Prihvatiti"I"Vrsta sadržaja”Zaglavlja po potrebi. Tada ćemo pokušati potrošiti REST API s potpunim razvrstavanjem i uklanjanjem oznake Foo Resurs - i s JSON-om i s XML-om.

5.1. Dohvaćanje resursa s br Prihvatiti Zaglavlje

@Test public void testGetFoo () {String URI = “// localhost: 8080 / spring-boot-rest / foos / {id}"; RestTemplate restTemplate = novi RestTemplate (); Foo foo = restTemplate.getForObject (URI, Foo. class, "1"); Assert.assertEquals (novi cijeli broj (1), foo.getId ());}

5.2. Dohvaćanje resursa sa aplikacija / xml Prihvati zaglavlje

Ajmo sad eksplicitno dohvatiti resurs kao XML prikaz. Definirat ćemo skup pretvarača i postaviti ih na RestTemplate.

Budući da trošimo XML, koristit ćemo isti XStream marshaller kao i prije:

@Test javna praznina givenConsumingXml_whenReadingTheFoo_thenCorrect () {URI niza = BASE_URI + "foos / {id}"; RestTemplate restTemplate = novi RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); HttpHeaders zaglavlja = novi HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_XML)); HttpEntity entitet = novi HttpEntity (zaglavlja); ResponseEntity odgovor = restTemplate.exchange (URI, HttpMethod.GET, entitet, Foo.class, "1"); Foo resurs = response.getBody (); assertThat (resource, notNullValue ()); } privatni popis getMessageConverters () {XStreamMarshaller marshaller = novi XStreamMarshaller (); MarshallingHttpMessageConverter marshallingConverter = novo MarshallingHttpMessageConverter (marshaller); Popis pretvarači = ArrayList(); converters.add (marshallingConverter); povratni pretvarači; }

5.3. Dohvaćanje resursa sa aplikacija / json Prihvati zaglavlje

Slično tome, konzumirajmo REST API tako što ćemo zatražiti JSON:

@Test javna praznina givenConsumingJson_whenReadingTheFoo_thenCorrect () {URI niza = BASE_URI + "foos / {id}"; RestTemplate restTemplate = novi RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); HttpHeaders zaglavlja = novi HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_JSON)); HttpEntity entitet = novi HttpEntity (zaglavlja); ResponseEntity odgovor = restTemplate.exchange (URI, HttpMethod.GET, entitet, Foo.class, "1"); Foo resurs = response.getBody (); assertThat (resource, notNullValue ()); } privatni popis getMessageConverters () {Popis pretvarači = novi ArrayList(); converters.add (novi MappingJackson2HttpMessageConverter ()); povratni pretvarači; }

5.4. Ažurirajte resurs s XML-om Vrsta sadržaja

Napokon, također pošaljite JSON podatke REST API-ju i navedite vrstu medija tih podataka putem Vrsta sadržaja Zaglavlje:

@Test javna praznina givenConsumingXml_whenWritingTheFoo_thenCorrect () {URI niza = BASE_URI + "foos / {id}"; RestTemplate restTemplate = novi RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); Foo resurs = novi Foo (4, "jason"); HttpHeaders zaglavlja = novi HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_JSON)); headers.setContentType ((MediaType.APPLICATION_XML)); HttpEntity entitet = novi HttpEntity (resurs, zaglavlja); ResponseEntity odgovor = restTemplate.exchange (URI, HttpMethod.PUT, entitet, Foo.class, resource.getId ()); Foo fooResponse = response.getBody (); Assert.assertEquals (resource.getId (), fooResponse.getId ()); }

Ono što je ovdje zanimljivo jest da možemo kombinirati vrste medija - šaljemo XML podatke, ali čekamo JSON podatke s poslužitelja. To pokazuje koliko je zapravo moćan mehanizam za pretvorbu Spring.

6. Zaključak

U ovom uputstvu pogledali smo kako nam Spring MVC omogućuje da odredimo i u potpunosti prilagodimo pretvarače Http poruka u automatski preusmjerava / uklanja odjavne jedinice Java i iz XML-a ili JSON-a. Ovo je, naravno, pojednostavnjena definicija, a postoji još toliko toga što mehanizam za pretvorbu poruka može učiniti - kao što vidimo iz posljednjeg testnog primjera.

Također smo pogledali kako iskoristiti isti snažni mehanizam s RestTemplate klijent - što dovodi do potpuno sigurnog načina konzumiranja API-ja.

Kao i uvijek, kôd predstavljen u ovom članku dostupan je na Githubu.


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