Obrada JSON-a u Javi EE 7

1. Pregled

Ovaj će vam članak pokazati kako obraditi JSON koristeći samo jezgru Java EE, bez upotrebe nezavisnih ovisnosti poput Jerseyja ili Jacksona. Gotovo sve što ćemo koristiti pruža paket javax.json.

2. Pisanje predmeta u JSON Niz

Pretvaranje Java objekta u JSON Niz je super jednostavno. Pretpostavimo da imamo jednostavan Osoba razred:

javna klasa Osoba {private String firstName; private String lastName; privatni datum datum rođenja; // geteri i postavljači}

Da pretvorite instancu te klase u JSON Niz, prvo moramo stvoriti instancu JsonObjectBuilder i dodajte parove svojstva / vrijednosti pomoću dodati() metoda:

JsonObjectBuilder objectBuilder = Json.createObjectBuilder () .add ("firstName", person.getFirstName ()) .add ("lastName", person.getLastName ()) .add ("datum rođenja", novi SimpleDateFormat ("DD / MM / GGGGG ") .format (person.getBirthdate ()));

Primijetite da dodati() metoda ima nekoliko preopterećenih verzija. Kao drugi parametar može primiti većinu primitivnih tipova (kao i objekte u okvirima).

Nakon što završimo s postavljanjem svojstava, samo trebamo objekt zapisati u Niz:

JsonObject jsonObject = objectBuilder.build (); Niz jsonString; probajte (Writer Writer = novi StringWriter ()) {Json.createWriter (Writer) .write (jsonObject); jsonString = writer.toString (); }

I to je to! Stvoreno Niz izgledat će ovako:

{"firstName": "Michael", "lastName": "Scott", "datedate": "15.06.1978."}

2.1. Koristeći JsonArrayBuilder za izgradnju nizova

Sada, da bismo našem primjeru dodali malo više složenosti, pretpostavimo da Osoba klasa je izmijenjena kako bi se dodalo novo svojstvo pod nazivom e-mailova koji će sadržavati popis adresa e-pošte:

javna klasa Osoba {private String firstName; private String lastName; privatni Datum rođenja; privatne e-adrese s popisa; // geteri i postavljači}

Da biste dodali sve vrijednosti s tog popisa na JsonObjectBuilder trebat će nam pomoć JsonArrayBuilder:

JsonArrayBuilder arrayBuilder = Json.createArrayBuilder (); for (String email: person.getEmails ()) {arrayBuilder.add (email); } objectBuilder.add ("e-adrese", arrayBuilder);

Primijetite da koristimo još jednu preopterećenu verziju dodati() metoda koja traje a JsonArrayBuilder objekt kao drugi parametar.

Pa, pogledajmo generirani String za Osoba objekt s dvije adrese e-pošte:

{"firstName": "Michael", "lastName": "Scott", "datedate": "06/15/1978", "e-mailovi": ["[email protected]", "[email protected]"]}

2.2. Oblikovanje rezultata s PRETTY_PRINTING

Dakle, uspješno smo pretvorili Java objekt u valjani JSON Niz. Sada, prije nego što prijeđemo na sljedeći odjeljak, dodajte malo jednostavnog formatiranja kako bi izlaz bio "JSON-sličan" i lakši za čitanje.

U prethodnim primjerima stvorili smo a JsonWriter koristeći se izravnim Json.createWriter () statička metoda. Da bi se dobila veća kontrola nad generiranim Niz, iskoristit ćemo Javu 7 JsonWriterFactory sposobnost stvaranja pisača s određenom konfiguracijom.

Mapa config = new HashMap (); config.put (JsonGenerator.PRETTY_PRINTING, točno); JsonWriterFactory writerFactory = Json.createWriterFactory (konfiguracija); Niz jsonString; try (Writer Writer = new StringWriter ()) {writerFactory.createWriter (Writer) .write (jsonObject); jsonString = writer.toString (); }

Kôd može izgledati pomalo opširno, ali stvarno ne čini puno.

Prvo, stvara primjerak JsonWriterFactory prosljeđivanje mape konfiguracije svom konstruktoru. Karta sadrži samo jedan unos koji postavlja vrijednost true na svojstvo PRETTY_PRINTING. Zatim koristimo tu tvorničku instancu za izradu programa za pisanje, umjesto da koristimo Json.createWriter ().

Novi izlaz sadržavat će prepoznatljive prijelome redaka i tablice koje karakteriziraju JSON Niz:

{"firstName": "Michael", "lastName": "Scott", "datum rođenja": "15.06.1978.", "e-mailovi": ["[email protected]", "[email protected]"]}

3. Izgradnja Jave Objekt Od Niz

Sada napravimo suprotnu operaciju: pretvorimo JSON Niz u Java objekt.

Glavni dio procesa pretvorbe vrti se oko JsonObject. Da biste stvorili instancu ove klase, upotrijebite statičku metodu Json.createReader () nakon čega slijedi readObject ():

Čitač JsonReader = Json.createReader (novi StringReader (jsonString)); JsonObject jsonObject = reader.readObject ();

The createReader () metoda uzima an InputStream kao parametar. U ovom primjeru koristimo a StringReader, budući da je naš JSON sadržan u a Niz objekt, ali ista bi se metoda mogla koristiti za čitanje sadržaja iz datoteke, na primjer, pomoću FileInputStream.

Uz primjerak JsonObject pri ruci, svojstva možemo čitati pomoću getString () metodu i dodijelite dobivene vrijednosti novostvorenoj instanci našeg Osoba razred:

Osoba osoba = nova osoba (); person.setFirstName (jsonObject.getString ("firstName")); person.setLastName (jsonObject.getString ("lastName")); person.setBirthdate (dateFormat.parse (jsonObject.getString ("datum rođenja")));

3.1. Koristeći JsonArray dobiti Popis Vrijednosti

Trebat ćemo koristiti posebnu klasu, koja se zove JsonArray za izdvajanje vrijednosti popisa iz JsonObject:

JsonArray e-adreseJson = jsonObject.getJsonArray ("e-adrese"); Popis e-adresa = novi ArrayList (); za (JsonString j: emailsJson.getValuesAs (JsonString.class)) {emails.add (j.getString ()); } person.setEmails (e-mailovi);

To je to! Stvorili smo potpunu instancu Osoba od Jsona Niz.

4. Upit za vrijednosti

Pretpostavimo sada da nas zanima vrlo specifičan dio podataka koji se nalazi unutar JSON-a Niz.

Razmotrite JSON u nastavku kako predstavlja klijenta iz trgovine za kućne ljubimce. Recimo da iz nekog razloga s popisa kućnih ljubimaca trebate dobiti ime trećeg ljubimca:

{"ownerName": "Robert", "pets": [{"name": "Kitty", "type": "cat"}, {"name": "Rex", "type": "dog"}, {"name": "Jake", "type": "dog"}]}

Pretvaranje cijelog teksta u Java objekt samo da bi se dobila jedna vrijednost ne bi bilo vrlo učinkovito. Dakle, provjerimo nekoliko strategija za postavljanje upita za JSON Žice bez da je morao proći cijelu kalvariju pretvorbe.

4.1. Upiti pomoću API-ja objektnog modela

Upit za vrijednost svojstva s poznatim mjestom u JSON strukturi je jednostavan. Možemo upotrijebiti primjerak JsonObject, ista klasa korištena u prethodnim primjerima:

Čitač JsonReader = Json.createReader (novi StringReader (jsonString)); JsonObject jsonObject = reader.readObject (); String searchResult = jsonObject .getJsonArray ("kućni ljubimci") .getJsonObject (2) .getString ("name"); 

Kvaka je ovdje u navigaciji jsonObject svojstva koristeći ispravan redoslijed dobiti*() metode.

U ovom primjeru prvo dobivamo referencu na popis "kućnih ljubimaca" pomoću getJsonArray (), koji vraća popis s 3 zapisa. Zatim, koristimo getJsonObject () metoda, koja uzima indeks kao parametar, vraćajući drugi JsonObject predstavljajući treću stavku na popisu. Konačno, koristimo getString () da dobijemo vrijednost niza koju tražimo.

4.2. Upiti pomoću streaming API-ja

Drugi način izvođenja preciznih upita na JSON-u Niz koristi Streaming API koji ima JsonParser kao svoju glavnu klasu.

JsonParser pruža izuzetno brz pristup JS-u samo za čitanje, s nedostatkom što je nešto složeniji od objektnog modela:

JsonParser jsonParser = Json.createParser (novi StringReader (jsonString)); broj brojeva = 0; Rezultat niza = null; while (jsonParser.hasNext ()) {Event e = jsonParser.next (); if (e == Event.KEY_NAME) {if (jsonParser.getString (). equals ("name")) {jsonParser.next (); if (++ count == 3) {rezultat = jsonParser.getString (); pauza; }}}}

Ovaj primjer daje isti rezultat kao i prethodni. Vraća Ime od trećeg ljubimca u kućni ljubimci popis.

Jednom JsonParser izrađuje se pomoću Json.createParser (), trebamo upotrijebiti iterator (otuda i "pristup prema naprijed" JsonParser) za kretanje kroz JSON tokene dok ne dođemo do svojstva (ili svojstava) koje tražimo.

Svaki put kad prođemo kroz iterator prelazimo na sljedeći token JSON podataka. Stoga moramo biti oprezni kako bismo provjerili ima li trenutni token očekivani tip. To se postiže provjerom Događaj vratio Sljedeći() poziv.

Postoji mnogo različitih vrsta žetona. U ovom primjeru nas zanima KEY_NAME tipovi, koji predstavljaju ime svojstva (npr. "ownerName", "pets", "name", "type"). Jednom kad smo zakoračili kroz KEY_NAME token s vrijednošću "name" po treći put, znamo da će sljedeći token sadržavati vrijednost niza koja predstavlja ime trećeg ljubimca s popisa.

Ovo je definitivno teže nego koristiti API objektnog modela, posebno za složenije JSON strukture. Izbor između jednog ili drugog, kao i uvijek, ovisi o konkretnom scenariju s kojim ćete se nositi.

5. Zaključak

Puno smo jednostavnih primjera pokrili Java EE JSON Processing API. Da biste naučili druge zanimljive stvari o obradi JSON-a, pogledajte našu seriju članaka Jackson.

Provjerite izvorni kod klasa korištenih u ovom članku, kao i neke jedinične testove, u našem GitHub spremištu.