Uvod u Jackson ObjectMapper

1. Pregled

Ovaj se vodič fokusira na razumijevanje Jacksona ObjectMapper klase i kako serializirati Java objekte u JSON i deserializirati JSON niz u Java objekte.

Da biste razumjeli više o Jackson knjižnici općenito, Jackson Tutorial je dobro mjesto za početak.

2. Ovisnosti

Prvo dodajmo sljedeće ovisnosti na pom.xml:

 com.fasterxml.jackson.core jackson-databind 2.11.1 

Ova ovisnost također će tranzitivno dodati sljedeće knjižnice na put predavanja:

  1. Jacksonove bilješke
  2. jackson-core

Uvijek koristite najnovije verzije središnjeg spremišta Maven za jackson-databind.

3. Čitanje i pisanje pomoću ObjectMapper

Počnimo s osnovnim operacijama čitanja i pisanja.

Jednostavno readValue API ObjectMapper je dobra ulazna točka. Pomoću njega možemo raščlaniti ili deserializirati JSON sadržaj u Java objekt.

Također, na strani pisanja, možemo koristiti writeValue API za serializaciju bilo kojeg Java objekta kao JSON izlaza.

Koristit ćemo sljedeće Automobil klasa s dva polja kao objektom za serializaciju ili deserializaciju kroz ovaj članak:

javni razred automobila {private String boja; tip privatnog niza; // postavljači standardnih dohvata}

3.1. Java objekt za JSON

Pogledajmo prvi primjer serializacije Java objekta u JSON pomoću writeValue metoda ObjectMapper razred:

ObjectMapper objectMapper = novi ObjectMapper (); Automobil = novi automobil ("žuti", "renault"); objectMapper.writeValue (nova datoteka ("target / car.json"), auto); 

Rezultat gore navedenog u datoteci bit će:

{"color": "yellow", "type": "renault"} 

Metode writeValueAsString i writeValueAsBytes od ObjectMapper klasa generira JSON iz Java objekta i vraća generirani JSON kao niz ili kao bajtni niz:

Niz carAsString = objectMapper.writeValueAsString (automobil); 

3.2. JSON za Java objekt

Ispod je jednostavan primjer pretvaranja JSON Stringa u Java objekt pomoću ObjectMapper razred:

Niz json = "{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" BMW \ "}"; Car car = objectMapper.readValue (json, Car.class); 

The readValue () funkcija također prihvaća druge oblike unosa, poput datoteke koja sadrži JSON niz:

Car car = objectMapper.readValue (nova datoteka ("src / test / resources / json_car.json"), Car.class);

ili URL:

Car car = objectMapper.readValue (novi URL ("datoteka: src / test / resources / json_car.json"), Car.class);

3.3. JSON Jacksonu JsonNode

JSON se može raščlaniti na JsonNode objekt i koristi se za dohvaćanje podataka s određenog čvora:

Niz json = "{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" FIAT \ "}"; JsonNode jsonNode = objectMapper.readTree (json); Boja niza = jsonNode.get ("boja"). AsText (); // Izlaz: boja -> Crna 

3.4. Stvaranje Java popisa iz niza JSON niza

JSON možemo raščlaniti u obliku niza na popis objekata Java pomoću a TypeReference:

Niz jsonCarArray = "[{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" BMW \ "}, {\" boja \ ": \" Crvena \ ", \" vrsta \ ": \ "FIAT \"}] "; Popis listCar = objectMapper.readValue (jsonCarArray, novi TypeReference(){}); 

3.5. Izrada Java mape iz JSON niza

Slično tome, možemo raščlaniti JSON u Javu Karta:

Niz json = "{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" BMW \ "}"; Map map = objectMapper.readValue (json, novi TypeReference(){}); 

4. Napredne značajke

Jedna od najvećih prednosti Jackson biblioteke je vrlo prilagodljiv postupak serializacije i deserializacije.

U ovom ćemo odjeljku proći kroz neke napredne značajke gdje se ulazni ili izlazni JSON odgovor mogu razlikovati od objekta koji generira ili troši odgovor.

4.1. Konfiguriranje značajke serializacije ili deserijalizacije

Tijekom pretvaranja JSON objekata u Java klase, u slučaju da JSON niz ima neka nova polja, zadani postupak rezultirat će iznimkom:

Niz jsonString = "{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" Fiat \ ", \" godina \ ": \" 1970 \ "}"; 

JSON niz u gornjem primjeru u zadanom postupku raščlanjivanja Java objekta za Razredni automobil rezultirat će NeprepoznatiPropertyException iznimka.

Kroz konfigurirati metodu, možemo proširiti zadani postupak tako da zanemarimo nova polja:

objectMapper.configure (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); Automobil auto = objectMapper.readValue (jsonString, Car.class); JsonNode jsonNodeRoot = objectMapper.readTree (jsonString); JsonNode jsonNodeYear = jsonNodeRoot.get ("godina"); Godina niza = jsonNodeYear.asText (); 

Još jedna opcija temelji se na FAIL_ON_NULL_FOR_PRIMITIVES, koji definira da li null dopuštene su vrijednosti za primitivne vrijednosti:

objectMapper.configure (DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); 

Slično tome, FAIL_ON_NUMBERS_FOR_ENUM kontrolira smije li se vrijednosti nabrajanja serializirati / deserializirati kao brojevi:

objectMapper.configure (DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);

Sveobuhvatan popis značajki serializacije i deserializacije možete pronaći na službenim stranicama.

4.2. Stvaranje prilagođenog serializatora ili deserijalizatora

Još jedna bitna značajka ObjectMapper klasa je sposobnost registracije prilagođenog serializatora i deserijalizatora.

Prilagođeni serializatori i deserializatori vrlo su korisni u situacijama kada se ulazni ili izlazni JSON odgovor razlikuje po strukturi od Java klase u koju mora biti serializiran ili deserializiran.

Ispod je primjer prilagođenog JSON serializatora:

javna klasa CustomCarSerializer proširuje StdSerializer {public CustomCarSerializer () {this (null); } javni CustomCarSerializer (klasa t) {super (t); } @Override public void serialize (automobil, JsonGenerator jsonGenerator, SerializerProvider serializer) {jsonGenerator.writeStartObject (); jsonGenerator.writeStringField ("car_brand", car.getType ()); jsonGenerator.writeEndObject (); }} 

Ovaj prilagođeni serializator može se pozvati ovako:

Mapa ObjectMapper = novi ObjectMapper (); Modul SimpleModule = novi SimpleModule ("CustomCarSerializer", nova verzija (1, 0, 0, null, null, null)); module.addSerializer (Car.class, novi CustomCarSerializer ()); mapper.registerModule (modul); Automobil = novi automobil ("žuti", "renault"); Niz carJson = mapper.writeValueAsString (auto); 

Evo što Automobil izgleda (kao JSON izlaz) na strani klijenta:

var carJson = {"car_brand": "renault"} 

I evo primjera prilagođeni JSON deserijalizator:

javna klasa CustomCarDeserializer proširuje StdDeserializer {public CustomCarDeserializer () {this (null); } javni CustomCarDeserializer (klasa vc) {super (vc); } @Override public Car deserialize (JsonParser parser, DeserializationContext deserializer) {Car car = new Car (); ObjectCodec codec = parser.getCodec (); JsonNode čvor = codec.readTree (parser); // pokušajte uhvatiti blok JsonNode colorNode = node.get ("boja"); Boja niza = colorNode.asText (); car.setColor (boja); povratak automobila; }} 

Ovaj se prilagođeni deserijalizator može pozvati na ovaj način:

Niz json = "{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" BMW \ "}"; Mapa ObjectMapper = novi ObjectMapper (); Modul SimpleModule = novi SimpleModule ("CustomCarDeserializer", nova verzija (1, 0, 0, null, null, null)); module.addDeserializer (Car.class, novi CustomCarDeserializer ()); mapper.registerModule (modul); Automobil automobila = mapper.readValue (json, Car.class); 

4.3. Rukovanje formatima datuma

Zadana serializacija java.util.Datum stvara broj, tj. vremensku oznaku epohe (broj milisekundi od 1. siječnja 1970., UTC). Ali ovo nije baš čitljivo za ljude i zahtijeva daljnju pretvorbu kako bi se prikazalo u čitljivom formatu.

Zamotajmo Automobil primjer koji smo do sada koristili unutar Zahtjev razred s Datum kupnje svojstvo:

zahtjev javne klase {osobni automobil; privatno Datum datum Kupljeno; // postavljači standardnih dohvata} 

Da biste kontrolirali format Stringa datuma i postavili ga na, npr. gggg-MM-dd HH: mm a z, razmotrite sljedeći isječak:

ObjectMapper objectMapper = novi ObjectMapper (); DateFormat df = novi SimpleDateFormat ("yyyy-MM-dd HH: mm a z"); objectMapper.setDateFormat (df); Niz carAsString = objectMapper.writeValueAsString (zahtjev); // izlaz: {"car": {"color": "yellow", "type": "renault"}, "datePurchased": "03.07.2016. 11:43 CEST"} 

Da biste saznali više o serijaliziranju datuma s Jacksonom, pročitajte naš detaljniji opis.

4.4. Rukovanje zbirkama

Još jedna mala, ali korisna značajka dostupna putem DeserializacijaFeature klasa je sposobnost generiranja vrste kolekcije koju želimo iz odgovora JSON niza.

Na primjer, rezultat možemo generirati kao niz:

Niz jsonCarArray = "[{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" BMW \ "}, {\" boja \ ": \" Crvena \ ", \" vrsta \ ": \ "FIAT \"}] "; ObjectMapper objectMapper = novi ObjectMapper (); objectMapper.configure (DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, istina); Car [] cars = objectMapper.readValue (jsonCarArray, Car []. Klasa); // tiskani automobili

Ili kao Popis:

Niz jsonCarArray = "[{\" boja \ ": \" Crna \ ", \" vrsta \ ": \" BMW \ "}, {\" boja \ ": \" Crvena \ ", \" vrsta \ ": \ "FIAT \"}] "; ObjectMapper objectMapper = novi ObjectMapper (); Popis listCar = objectMapper.readValue (jsonCarArray, novi TypeReference() {}); // tiskani automobili

Više informacija o rukovanju zbirkama s Jacksonom dostupno je ovdje.

5. Zaključak

Jackson je čvrsta i zrela JSON-ova biblioteka za serializaciju / deserializaciju za Javu. The ObjectMapper API pruža jednostavan način raščlanjivanja i generiranja JSON objekata odgovora s velikom fleksibilnošću. Ovaj je članak raspravljao o glavnim značajkama zbog kojih je knjižnica toliko popularna.

Izvorni kod koji prati članak nalazi se na GitHubu.