Http Message Converters with the Spring Framework

1. Oversikt

Denne artikkelen beskriver hvordan du konfigurerer HttpMessageConverters på våren.

Enkelt sagt, vi kan bruke meldingsomformere til å marshallere og unmarshall Java-objekter til og fra JSON, XML, etc - over HTTP.

2. Grunnleggende

2.1. Aktiver web-MVC

Til å begynne med må webapplikasjonen være konfigurert med Spring MVC-støtte. En praktisk og veldig tilpassbar måte å gjøre dette på er å bruke @EnableWebMvc kommentar:

@EnableWebMvc @ Configuration @ ComponentScan ({"com.baeldung.web"}) offentlig klasse WebConfig implementerer WebMvcConfigurer {...}

Merk at denne klassen implementerer WebMvcConfigurer - som vil tillate oss å endre standardlisten over Http Converters med vår egen.

2.2. Standard meldingsomformere

Som standard er følgende HttpMessageConverter Forekomster er forhåndsaktivert:

  • ByteArrayHttpMessageConverter - konverterer byte-arrays
  • StringHttpMessageConverter - konverterer strenger
  • ResourceHttpMessageConverter - konverterer org.springframework.core.io.Ressurs for alle typer oktettstrømmer
  • SourceHttpMessageConverter - konverterer javax.xml.transform.Source
  • FormHttpMessageConverter - konverterer skjemadata til / fra en MultiValueMap.
  • Jaxb2RootElementHttpMessageConverter - konverterer Java-objekter til / fra XML (bare lagt til hvis JAXB2 er til stede på klassestien)
  • MappingJackson2HttpMessageConverter - konverterer JSON (bare lagt til hvis Jackson 2 er til stede på klassestien)

  • MappingJacksonHttpMessageConverter - konverterer JSON (bare lagt til hvis Jackson er til stede på klassestien)
  • AtomFeedHttpMessageConverter - konverterer Atom-feeds (bare lagt til hvis Roma er til stede på klassestien)
  • RssChannelHttpMessageConverter - konverterer RSS-feeder (bare lagt til hvis Roma er til stede på klassestien)

3. Klient-server-kommunikasjon - Bare JSON

3.1. Innholdsforhandling på høyt nivå

Hver HttpMessageConverter implementering har en eller flere tilknyttede MIME-typer.

Når du mottar en ny forespørsel, Våren vil bruke “Aksepterer”-Hode for å bestemme medietypen den trenger å svare med.

Den vil da prøve å finne en registrert omformer som er i stand til å håndtere den spesifikke medietypen. Til slutt vil den bruke dette til å konvertere enheten og sende svaret tilbake.

Prosessen er lik for å motta en forespørsel som inneholder JSON-informasjon. Rammeverket vil bruke "Innholdstype”-Tittel for å bestemme medietypen til forespørselen.

Den vil da søke etter en HttpMessageConverter som kan konvertere kroppen sendt av klienten til et Java-objekt.

La oss avklare dette med et raskt eksempel:

  • klienten sender en GET-forespørsel til / foos med Aksepterer topptekst satt til søknad / json - for å få alle Foo ressurser som JSON
  • de Foo Spring Controller treffes og returnerer det tilsvarende Foo Java-enheter
  • Spring bruker deretter en av Jackson-meldingsomformerne for å samle enhetene til JSON

La oss nå se på detaljene i hvordan dette fungerer - og hvordan vi kan utnytte @ResponseBody og @RequestBody kommentarer.

3.2. @ResponseBody

@ResponseBody på en Controller-metode indikerer for Spring at returverdien av metoden serialiseres direkte til hoveddelen av HTTP-svaret. Som diskutert ovenfor, “Aksepterer”-Overskrift spesifisert av klienten vil bli brukt til å velge riktig Http Converter for å samle enheten.

La oss se på et enkelt eksempel:

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

Nå vil klienten spesifisere "Godta" overskriften til søknad / json i forespørselen - eksempel krølle kommando:

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

De Foo klasse:

offentlig klasse Foo {privat lang id; privat strengnavn; }

Og Http-responsorganet:

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

3.3. @Fotball

Vi kan bruke @Fotball kommentar om argumentet til en Controller-metode for å indikere at hoveddelen av HTTP-forespørselen er deserialisert til den bestemte Java-enheten. For å bestemme riktig omformer vil Spring bruke "Content-Type" -overskriften fra klientforespørselen.

La oss se på et eksempel:

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

La oss deretter konsumere dette med et JSON-objekt - vi spesifiserer “Content-Type å være søknad / json:

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

Vi får tilbake 200 OK - et vellykket svar:

HTTP / 1.1 200 OK Server: Apache-Coyote / 1.1 Innholdslengde: 0 Dato: Fre, 10. januar 2014 11:18:54 GMT

4. Konfigurasjon av egendefinerte omformere

Vi kan også tilpasse meldingsomformerne ved å implementere WebMvcConfigurer grensesnitt og overordnet configureMessageConverters metode:

@EnableWebMvc @Configuration @ComponentScan ({"com.baeldung.web"}) offentlig klasse WebConfig implementerer WebMvcConfigurer {@Override public void configureMessageConverters (List omformere) {messageConverters.add (createXmlHttpMessageConverter ()); messageConverters.add (ny MappingJackson2HttpMessageConverter ()); } private HttpMessageConverter createXmlHttpMessageConverter () {MarshallingHttpMessageConverter xmlConverter = ny MarshallingHttpMessageConverter (); XStreamMarshaller xstreamMarshaller = ny XStreamMarshaller (); xmlConverter.setMarshaller (xstreamMarshaller); xmlConverter.setUnmarshaller (xstreamMarshaller); returnere xmlConverter; }}

I dette eksemplet lager vi en ny omformer - MarshallingHttpMessageConverter - og bruke Spring XStream-støtten til å konfigurere den. Dette gir stor fleksibilitet siden Vi jobber med API-er på lavt nivå i det underliggende marshalling-rammeverket - i dette tilfellet XStream - og vi kan konfigurere det slik vi vil.

Merk at dette eksemplet krever at du legger til XStream-biblioteket i klassestien.

Vær også oppmerksom på at ved å utvide denne støtteklassen, vi mister standardmeldingskonvertere som tidligere var forhåndsregistrert.

Vi kan selvfølgelig nå gjøre det samme for Jackson - ved å definere vår egen MappingJackson2HttpMessageConverter. Vi kan nå angi en egendefinert ObjectMapper på denne omformeren og ha den konfigurert slik vi trenger det.

I dette tilfellet var XStream den valgte marshaller / unmarshaller implementeringen, men andre liker CastorMarshaller kan også brukes.

På dette punktet - med XML aktivert på baksiden - kan vi konsumere API-en med XML-representasjoner:

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

4.1. Vårstøvelstøtte

Hvis vi bruker Spring Boot, kan vi unngå å implementere WebMvcConfigurer og legge til alle meldingsomformerne manuelt som vi gjorde ovenfor.

Vi kan bare definere forskjellige HttpMessageConverter bønner i sammenheng, og Spring Boot vil legge dem automatisk til autokonfigurasjonen som den oppretter:

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

5. Bruke Spring’s RestTemplate Med Http Message Converters

I tillegg til på serversiden kan Http Message Conversion konfigureres på klientsiden på våren RestTemplate.

Vi skal konfigurere malen med “Aksepterer”Og”Innholdstype”Overskrifter når det er aktuelt. Så prøver vi å konsumere REST API med full marshalling og unmarshalling av Foo Ressurs - både med JSON og med XML.

5.1. Henter ressursen med nr Aksepterer Overskrift

@Test offentlig ugyldig testGetFoo () {String URI = “// localhost: 8080 / spring-boot-rest / foos / {id}"; RestTemplate restTemplate = new RestTemplate (); Foo foo = restTemplate.getForObject (URI, Foo. klasse, "1"); Assert.assertEquals (nytt heltal (1), foo.getId ());}

5.2. Henter en ressurs med applikasjon / xml Godta topptekst

La oss nå eksplisitt hente ressursen som en XML-representasjon. Vi skal definere et sett med omformere og sette disse på RestTemplate.

Fordi vi bruker XML, skal vi bruke samme XStream marshaller som før:

@Test offentlig ugyldig gittConsumingXml_whenReadingTheFoo_thenCorrect () {String URI = BASE_URI + "foos / {id}"; RestTemplate restTemplate = ny RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); HttpHeaders headers = nye HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_XML)); HttpEntity entity = new HttpEntity (headers); ResponseEntity response = restTemplate.exchange (URI, HttpMethod.GET, entity, Foo.class, "1"); Foo ressurs = respons.getBody (); assertThat (resource, notNullValue ()); } privat liste getMessageConverters () {XStreamMarshaller marshaller = ny XStreamMarshaller (); MarshallingHttpMessageConverter marshallingConverter = ny MarshallingHttpMessageConverter (marshaller); Liste omformere = ArrayList(); converters.add (marshallingConverter); omformere; }

5.3. Henter en ressurs med søknad / json Godta topptekst

På samme måte, la oss nå konsumere REST API ved å be om JSON:

@Test offentlig ugyldig gittConsumingJson_whenReadingTheFoo_thenCorrect () {String URI = BASE_URI + "foos / {id}"; RestTemplate restTemplate = ny RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); HttpHeaders headers = nye HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_JSON)); HttpEntity entity = new HttpEntity (headers); ResponseEntity response = restTemplate.exchange (URI, HttpMethod.GET, entity, Foo.class, "1"); Foo ressurs = respons.getBody (); assertThat (resource, notNullValue ()); } privat liste getMessageConverters () {Liste omformere = ny ArrayList(); converters.add (ny MappingJackson2HttpMessageConverter ()); omformere; }

5.4. Oppdater en ressurs med XML Innholdstype

Til slutt, la oss også sende JSON-data til REST API og spesifisere medietypen for disse dataene via Innholdstype Overskrift:

@Test offentlig ugyldig gittConsumingXml_whenWritingTheFoo_thenCorrect () {String URI = BASE_URI + "foos / {id}"; RestTemplate restTemplate = ny RestTemplate (); restTemplate.setMessageConverters (getMessageConverters ()); Foo ressurs = ny Foo (4, "jason"); HttpHeaders headers = nye HttpHeaders (); headers.setAccept (Arrays.asList (MediaType.APPLICATION_JSON)); headers.setContentType ((MediaType.APPLICATION_XML)); HttpEntity entity = new HttpEntity (resource, headers); ResponseEntity response = restTemplate.exchange (URI, HttpMethod.PUT, entity, Foo.class, resource.getId ()); Foo fooResponse = respons.getBody (); Assert.assertEquals (resource.getId (), fooResponse.getId ()); }

Det som er interessant her er at vi kan blande medietypene - vi sender XML-data, men vi venter på JSON-data tilbake fra serveren. Dette viser hvor kraftig vårkonverteringsmekanismen egentlig er.

6. Konklusjon

I denne opplæringen så vi på hvordan Spring MVC tillater oss å spesifisere og tilpasse Http Message Converters til automatisk marshall / unmarshall Java-enheter til og fra XML eller JSON. Dette er selvfølgelig en forenklet definisjon, og det er så mye mer som konverteringsmekanismen for meldinger kan gjøre - som vi kan se fra det siste testeksemplet.

Vi har også sett på hvordan vi kan bruke den samme kraftige mekanismen med RestTemplate klient - noe som fører til en fullstendig typesikker måte å konsumere API på.

Som alltid er koden presentert i denne artikkelen tilgjengelig på Github.


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