Prevodníky správ HTTP s jarným rámcom

1. Prehľad

Tento článok popisuje ako konfigurovať HttpMessageConverters na jar.

Jednoducho povedané, môžeme použiť prevádzače správ na marshall a unmarshall objektov Java do az JSON, XML atď. - cez HTTP.

2. Základy

2.1. Povoliť webové MVC

Najskôr musí byť webová aplikácia nakonfigurovaný s podporou Spring MVC. Pohodlným a veľmi prispôsobiteľným spôsobom, ako to dosiahnuť, je použitie súboru @EnableWebMvc anotácia:

@EnableWebMvc @Configuration @ComponentScan ({"com.baeldung.web"}) verejná trieda WebConfig implementuje WebMvcConfigurer {...}

Upozorňujeme, že táto trieda implementuje WebMvcConfigurer - čo nám umožní zmeniť predvolený zoznam Http prevádzačov s vlastnými.

2.2. Predvolené prevádzače správ

Predvolene nasledovné HttpMessageConverter inštancie sú vopred povolené:

  • ByteArrayHttpMessageConverter - prevádza bajtové polia
  • StringHttpMessageConverter - prevádza reťazce
  • ResourceHttpMessageConverter - prevádza org.springframework.core.io.Resource pre akýkoľvek typ oktetového prúdu
  • SourceHttpMessageConverter - prevádza javax.xml.transform.Source
  • FormHttpMessageConverter - prevádza dáta formulára do / z a MultiValueMap.
  • Jaxb2RootElementHttpMessageConverter - prevádza objekty Java na / z XML (pridáva sa, iba ak je na triednej ceste JAXB2)
  • MappingJackson2HttpMessageConverter - prevádza JSON (pridáva sa, iba ak je v triede prítomný Jackson 2)

  • MappingJacksonHttpMessageConverter - prevádza JSON (pridáva sa, iba ak je Jackson v triede)
  • AtomFeedHttpMessageConverter - prevádza kanály Atom (pridané, iba ak je na trase cesty Rím)
  • RssChannelHttpMessageConverter Prevádza kanály RSS - (pridané, iba ak je na triednej ceste Rím)

3. Komunikácia klient-server - iba JSON

3.1. Vyjednávanie o obsahu na vysokej úrovni

Každý HttpMessageConverter implementácia má jeden alebo viac asociovaných typov MIME.

Pri prijímaní novej žiadosti Jar využije „súhlasiť”Určuje typ média, na ktorý musí reagovať.

Potom sa pokúsi nájsť registrovaného prevádzača, ktorý je schopný spracovať daný konkrétny typ média. Nakoniec to použije na prevod entity a odoslanie odpovede späť.

Proces je podobný pri prijímaní žiadosti, ktorá obsahuje informácie JSON. Rámec bude Použi "Druh obsahu„Hlavička na určenie typu média tela žiadosti.

Potom vyhľadá a HttpMessageConverter ktorý dokáže previesť telo odoslané klientom na objekt Java.

Poďme si to objasniť na krátkom príklade:

  • klient pošle žiadosť GET na adresu / foos s súhlasiť hlavička nastavená na aplikácia / json - dostať všetko Foo zdroje ako JSON
  • the Foo Ovládač pružiny je zasiahnutý a vráti zodpovedajúce Foo Entity Java
  • Spring potom použije jedného z Jacksonových prevádzačov správ na zaradenie entít do JSON

Pozrime sa teraz na špecifiká toho, ako to funguje - a ako môžeme využiť @ResponseBody a @RequestBody anotácie.

3.2. @ResponseBody

@ResponseBody na metóde Controller to naznačuje Springovi návratová hodnota metódy je serializovaná priamo do tela odpovede HTTP. Ako bolo uvedené vyššie, „súhlasiť”Hlavička zadaná klientom sa použije na výber vhodného prevádzača Http Converter na zaradenie entity.

Pozrime sa na jednoduchý príklad:

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

Teraz klient určí hlavičku „Prijať“ aplikácia / json v žiadosti - príklad zvlnenie príkaz:

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

The Foo trieda:

public class Foo {private long id; súkromné ​​meno reťazca; }

A orgán odpovede HTTP:

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

3.3. @RequestBody

Môžeme použiť @RequestBody anotácia k argumentu metódy Controller, ktorá sa má uviesť že telo požiadavky HTTP je deserializované na konkrétnu entitu Java. Na určenie vhodného prevádzača použije Spring hlavičku „Content-Type“ z požiadavky klienta.

Pozrime sa na príklad:

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

Ďalej to spotrebujme s objektom JSON - špecifikujeme „Content-Type byť aplikácia / json:

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

Dostávame späť 200 bodov - úspešná odpoveď:

HTTP / 1.1 200 OK Server: Apache-Coyote / 1.1 Content-Length: 0 Dátum: Pi, 10. januára 2014 11:18:54 GMT

4. Konfigurácia vlastných prevodníkov

Môžeme tiež prispôsobiť prevádzače správ implementáciou WebMvcConfigurer rozhranie a prvoradé configureMessageConverters metóda:

@EnableWebMvc @Configuration @ComponentScan ({"com.baeldung.web"}) verejná trieda WebConfig implementuje WebMvcConfigurer {@Override public void configureMessageConverters (zoznam prevádzače) {messageConverters.add (createXmlHttpMessageConverter ()); messageConverters.add (nový MappingJackson2HttpMessageConverter ()); } private HttpMessageConverter createXmlHttpMessageConverter () {MarshallingHttpMessageConverter xmlConverter = nový MarshallingHttpMessageConverter (); XStreamMarshaller xstreamMarshaller = nový XStreamMarshaller (); xmlConverter.setMarshaller (xstreamMarshaller); xmlConverter.setUnmarshaller (xstreamMarshaller); návrat xmlConverter; }}

V tomto príklade vytvárame nový prevodník - MarshallingHttpMessageConverter - a na jeho konfiguráciu použiť podporu Spring XStream. To dovtedy umožňuje veľkú flexibilitu pracujeme s nízkoúrovňovými API základného zriaďovacieho rámca - v tomto prípade XStream - a môžeme si ho nakonfigurovať, ako chceme.

Upozorňujeme, že tento príklad vyžaduje pridanie knižnice XStream do cesty triedy.

Uvedomte si tiež, že rozšírením tejto triedy podpory prichádzame o predvolené prevádzače správ, ktoré boli predtým predbežne zaregistrované.

Teraz samozrejme môžeme urobiť to isté pre Jacksona - definovaním toho nášho MappingJackson2HttpMessageConverter. Teraz môžeme nastaviť zvyk ObjectMapper na tomto prevodníku a nechať si ho nakonfigurovať tak, ako potrebujeme.

V tomto prípade bola vybratá implementácia Marshaller / Unmarshaller XStream, ostatným sa to však páči CastorMarshaller môžu byť tiež použité.

V tomto okamihu - s povoleným XML na zadnej strane - môžeme konzumovať API s reprezentáciami XML:

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

4.1. Podpora jarných topánok

Ak používame Spring Boot, môžeme sa vyhnúť implementácii WebMvcConfigurer a manuálne pridanie všetkých prevádzačov správ, ako sme to urobili vyššie.

Môžeme len definovať rôzne HttpMessageConverter fazule v kontexte a Spring Boot ich automaticky pridá do autokonfigurácie, ktorú vytvorí:

@Bean public HttpMessageConverter createXmlHttpMessageConverter () {MarshallingHttpMessageConverter xmlConverter = nový MarshallingHttpMessageConverter (); // ... vrátiť xmlConverter; }

5. Používanie Spring’s RestTemplate S prevádzačmi správ HTTP

Rovnako ako na strane servera, aj Http Message Conversion je možné nakonfigurovať na jar na strane klienta RestTemplate.

Konfigurujeme šablónu pomocou „súhlasiť“A„Druh obsahu”Hlavičky, ak je to vhodné. Potom sa pokúsime spotrebovať rozhranie REST API s plným zoradením a odobratím Foo Zdroj - ako s JSON, tak s XML.

5.1. Získanie zdroja pomocou č súhlasiť Hlavička

@Test public void testGetFoo () {String URI = “// localhost: 8080 / spring-boot-rest / foos / {id}"; RestTemplate restTemplate = new RestTemplate (); Foo foo = restTemplate.getForObject (URI, Foo. trieda, "1"); Assert.assertEquals (nové celé číslo (1), foo.getId ());}

5.2. Získanie zdroja pomocou prihláška / xml Prijať hlavičku

Poďme teraz explicitne načítať zdroj ako reprezentáciu XML. Budeme definovať množinu prevádzačov a nastavovať ich na RestTemplate.

Pretože spotrebúvame XML, budeme používať rovnakého zaraďovača XStream ako predtým:

@Test public void givenConsumingXml_whenReadingTheFoo_thenCorrect () {reťazec URI = BASE_URI + "foos / {id}"; RestTemplate restTemplate = nový RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); Hlavičky HttpHeaders = nové HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_XML)); HttpEntity entity = new HttpEntity (headers); ResponseEntity response = restTemplate.exchange (URI, HttpMethod.GET, entita, Foo.class, "1"); Foo resource = response.getBody (); assertThat (resource, notNullValue ()); } súkromný zoznam getMessageConverters () {XStreamMarshaller marshaller = nový XStreamMarshaller (); MarshallingHttpMessageConverter marshallingConverter = nový MarshallingHttpMessageConverter (marshaller); Zoznam prevádzače = ArrayList(); prevádzače.add (marshallingConverter); spätné meniče; }

5.3. Získanie zdroja pomocou aplikácia / json Prijať hlavičku

Podobne teraz poďme spotrebovať REST API a požiadať o JSON:

@Test public void givenConsumingJson_whenReadingTheFoo_thenCorrect () {String URI = BASE_URI + "foos / {id}"; RestTemplate restTemplate = nový RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); Hlavičky HttpHeaders = nové HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_JSON)); HttpEntity entity = new HttpEntity (headers); ResponseEntity response = restTemplate.exchange (URI, HttpMethod.GET, entita, Foo.class, "1"); Foo resource = response.getBody (); assertThat (resource, notNullValue ()); } súkromný zoznam getMessageConverters () {Zoznam prevádzače = nový ArrayList(); prevádzače.add (nový MappingJackson2HttpMessageConverter ()); spätné meniče; }

5.4. Aktualizujte zdroj pomocou XML Druh obsahu

Na záver poďme tiež poslať údaje JSON do rozhrania REST API a určiť typ média týchto údajov prostredníctvom Druh obsahu hlavička:

@Test public void givenConsumingXml_whenWritingTheFoo_thenCorrect () {reťazec URI = BASE_URI + "foos / {id}"; RestTemplate restTemplate = nový RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); Zdroj Foo = nový Foo (4, „jason“); Hlavičky HttpHeaders = nové HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_JSON)); headers.setContentType ((MediaType.APPLICATION_XML)); HttpEntity entity = new HttpEntity (zdroj, hlavičky); ResponseEntity response = restTemplate.exchange (URI, HttpMethod.PUT, entita, Foo.class, resource.getId ()); Foo fooResponse = response.getBody (); Assert.assertEquals (resource.getId (), fooResponse.getId ()); }

Zaujímavé tu je, že sme schopní kombinovať typy médií - posielame údaje XML, ale čakáme na údaje JSON späť zo servera. To ukazuje, aký silný je v skutočnosti mechanizmus jarnej premeny.

6. Záver

V tomto tutoriáli sme sa pozreli na to, ako nám Spring MVC umožňuje špecifikovať a plne prispôsobiť prevádzače správ HTTP automaticky zaraďovať / odnímať entity Java do az XML alebo JSON. Toto je samozrejme zjednodušujúca definícia a je tu oveľa viac, čo mechanizmus premeny správ dokáže - ako vidíme z posledného príkladu testu.

Pozreli sme sa tiež na to, ako využiť rovnako výkonný mechanizmus s RestTemplate klient - čo vedie k plne typovo bezpečnému spôsobu využívania API.

Ako vždy, kód uvedený v tomto článku je k dispozícii na stránkach Github.