JSON-behandling i Java EE 7

1. Oversikt

Denne artikkelen vil vise deg hvordan du behandler JSON ved kun å bruke Java EE, uten bruk av tredjepartsavhengigheter som Jersey eller Jackson. Nesten alt vi skal bruke er levert av javax.json-pakken.

2. Skrive et objekt til JSON String

Konvertering av et Java-objekt til en JSON String er superenkelt. La oss anta at vi har en enkel Person klasse:

offentlig klasse Person {privat streng fornavn; privat streng etternavn; privat fødselsdato; // getters og setters}

Å konvertere en forekomst av den klassen til en JSON String, først må vi lage en forekomst av JsonObjectBuilder og legg til eiendom / verdipar ved hjelp av legge til() metode:

JsonObjectBuilder objectBuilder = Json.createObjectBuilder () .add ("firstName", person.getFirstName ()) .add ("lastName", person.getLastName ()) .add ("fødselsdato", ny SimpleDateFormat ("DD / MM / ÅÅÅÅ ") .format (person.getBirthdate ()));

Legg merke til at legge til() metoden har noen overbelastede versjoner. Den kan motta de fleste av de primitive typene (så vel som boksede objekter) som sin andre parameter.

Når vi er ferdige med å sette egenskapene, trenger vi bare å skrive objektet til et String:

JsonObject jsonObject = objectBuilder.build (); String jsonString; prøv (Writer Writer = New StringWriter ()) {Json.createWriter (Writer) .write (jsonObject); jsonString = writer.toString (); }

Og det er det! Den genererte String vil se slik ut:

{"firstName": "Michael", "lastName": "Scott", "fødselsdato": "15.06.1978"}

2.1. Ved hjelp av JsonArrayBuilder å bygge arrays

Nå, for å legge til litt mer kompleksitet i eksemplet vårt, la oss anta at Person klasse ble endret for å legge til en ny eiendom kalt e-post som vil inneholde en liste over e-postadresser:

offentlig klasse Person {privat streng fornavn; privat streng etternavn; privat fødselsdato; private e-postmeldinger; // getters og setters}

For å legge til alle verdiene fra den listen i JsonObjectBuilder vi trenger hjelp fra JsonArrayBuilder:

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

Legg merke til at vi bruker enda en overbelastet versjon av legge til() metode som tar en JsonArrayBuilder objekt som andre parameter.

Så, la oss se på den genererte strengen for en Person objekt med to e-postadresser:

{"firstName": "Michael", "lastName": "Scott", "birthdate": "06/15/1978", "emails": ["[email protected]", "[email protected]"]}

2.2. Formatering av utdata med PRETTY_PRINTING

Så vi har vellykket konvertert et Java-objekt til en gyldig JSON String. Nå, før vi går til neste avsnitt, la oss legge til litt enkel formatering for å gjøre utdataene mer "JSON-aktige" og lettere å lese.

I de forrige eksemplene opprettet vi en JsonWriter bruker det enkle Json.createWriter () statisk metode. For å få mer kontroll over det genererte String, vil vi utnytte Java 7-er JsonWriterFactory muligheten til å lage en forfatter med en spesifikk konfigurasjon.

Map config = new HashMap (); config.put (JsonGenerator.PRETTY_PRINTING, true); JsonWriterFactory writerFactory = Json.createWriterFactory (config); String jsonString; prøv (Writer Writer = New StringWriter ()) {WriterFactory.createWriter (Writer) .write (jsonObject); jsonString = writer.toString (); }

Koden kan se litt ordentlig ut, men den gjør egentlig ikke mye.

For det første skaper det en forekomst av JsonWriterFactory overføring av et konfigurasjonskart til konstruktøren. Kartet inneholder bare en oppføring som setter seg til PRETTY_PRINTING-egenskapen. Deretter bruker vi den fabrikkinstansen til å lage en forfatter i stedet for å bruke Json.createWriter ().

Den nye utgangen vil inneholde de særegne linjeskiftene og tabellene som kjennetegner en JSON String:

{"firstName": "Michael", "lastName": "Scott", "birthdate": "06/15/1978", "emails": ["[email protected]", "[email protected]"]}

3. Å bygge en Java Gjenstand Fra en String

La oss nå gjøre den motsatte operasjonen: konvertere en JSON String inn i et Java-objekt.

Hoveddelen av konverteringsprosessen dreier seg om JsonObject. For å opprette en forekomst av denne klassen, bruk den statiske metoden Json.createReader () etterfulgt av readObject ():

JsonReader reader = Json.createReader (ny StringReader (jsonString)); JsonObject jsonObject = reader.readObject ();

De createReader () metoden tar en InputStream som parameter. I dette eksemplet bruker vi a Strengleser, siden vår JSON er inneholdt i en String objekt, men den samme metoden kan brukes til å lese innhold fra en fil, for eksempel ved hjelp av FileInputStream.

Med en forekomst av JsonObject For hånden kan vi lese egenskapene ved hjelp av getString () metode og tilordne de oppnådde verdiene til en nylig opprettet forekomst av vår Person klasse:

Personperson = ny person (); person.setFirstName (jsonObject.getString ("fornavn")); person.setLastName (jsonObject.getString ("etternavn")); person.setBirthdate (dateFormat.parse (jsonObject.getString ("fødselsdato")));

3.1. Ved hjelp av JsonArray å få Liste Verdier

Vi må bruke en spesiell klasse, kalt JsonArray for å trekke ut listeverdier fra JsonObject:

JsonArray emailsJson = jsonObject.getJsonArray ("emails"); Liste e-post = ny ArrayList (); for (JsonString j: emailsJson.getValuesAs (JsonString.class)) {emails.add (j.getString ()); } person.setEmails (e-post);

Det er det! Vi har opprettet en komplett forekomst av Person fra en Json String.

4. Spørring etter verdier

La oss anta at vi er interessert i en veldig spesifikk data som ligger inne i en JSON String.

Tenk på JSON nedenfor som representerer en klient fra en dyrebutikk. La oss si at du av en eller annen grunn må hente navnet på det tredje kjæledyret fra kjæledyrlisten:

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

Å konvertere hele teksten til et Java-objekt bare for å få en enkelt verdi, ville ikke være veldig effektivt. Så la oss sjekke et par strategier for å spørre JSON Strenger uten å måtte gå igjennom hele prøvelsen.

4.1. Spørring ved hjelp av Object Model API

Det er enkelt å spørre etter en eiendoms verdi med en kjent beliggenhet i JSON-strukturen. Vi kan bruke en forekomst av JsonObject, samme klasse som brukt i tidligere eksempler:

JsonReader reader = Json.createReader (ny StringReader (jsonString)); JsonObject jsonObject = reader.readObject (); String searchResult = jsonObject .getJsonArray ("pets") .getJsonObject (2) .getString ("name"); 

Fangsten her er å navigere gjennom jsonObject egenskaper ved å bruke riktig sekvens av få*() metoder.

I dette eksemplet får vi først en referanse til "kjæledyr" -listen ved hjelp av getJsonArray (), som returnerer en liste med 3 poster. Så bruker vi getJsonObject () metode, som tar en indeks som parameter, og returnerer en annen JsonObject som representerer det tredje elementet i listen. Til slutt bruker vi getString () for å få strengverdien vi leter etter.

4.2. Spørring ved hjelp av Streaming API

En annen måte å utføre presise spørsmål på en JSON String bruker Streaming API, som har JsonParser som hovedklasse.

JsonParser gir ekstremt rask, skrivebeskyttet, videre tilgang til JS, med ulempen å være noe mer komplisert enn Objektmodellen:

JsonParser jsonParser = Json.createParser (ny StringReader (jsonString)); int-antall = 0; Strengresultat = null; mens (jsonParser.hasNext ()) {Event e = jsonParser.next (); hvis (e == Event.KEY_NAME) {if (jsonParser.getString (). tilsvarer ("navn")) {jsonParser.next (); hvis (++ count == 3) {result = jsonParser.getString (); gå i stykker; }}}}

Dette eksemplet gir det samme resultatet som det forrige. Den returnerer Navn fra det tredje kjæledyret i kjæledyr liste.

En gang en JsonParser er opprettet ved hjelp av Json.createParser (), må vi bruke en iterator (derav “fremadgående” natur av JsonParser) for å navigere gjennom JSON-tokens til vi kommer til eiendommen (eller eiendommene) vi leter etter.

Hver gang vi går gjennom iteratoren, beveger vi oss til neste token av JSON-dataene. Så vi må være nøye med å sjekke om det nåværende tokenet har den forventede typen. Dette gjøres ved å sjekke Begivenhet returnert av neste () anrop.

Det er mange forskjellige typer tokens. I dette eksemplet er vi interessert i KEY_NAME typer, som representerer navnet på en eiendom (f.eks. "eiernavn", "kjæledyr", "navn", "type"). En gang gikk vi gjennom en KEY_NAME token med verdien "navn" for tredje gang, vet vi at neste token vil inneholde en strengverdi som representerer navnet på det tredje kjæledyret fra listen.

Dette er definitivt vanskeligere enn å bruke Object Model API, spesielt for mer kompliserte JSON-strukturer. Valget mellom det ene eller det andre, som alltid, avhenger av det spesifikke scenariet du skal håndtere.

5. Konklusjon

Vi har dekket mye bakken på Java EE JSON Processing API med et par enkle eksempler. For å lære andre kule ting om JSON-behandling, sjekk vår serie med Jackson-artikler.

Sjekk kildekoden til klassene som brukes i denne artikkelen, samt noen enhetstester, i GitHub-depotet vårt.


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