JSON-behandling i Java EE 7

1. Oversigt

Denne artikel viser dig, hvordan du behandler JSON kun ved hjælp af Java EE-kernen uden brug af tredjepartsafhængigheder som Jersey eller Jackson. Stort set alt, hvad vi bruger, leveres af javax.json-pakken.

2. Skrivning af et objekt til JSON Snor

Konvertering af et Java-objekt til en JSON Snor er super let. Lad os antage, at vi har en simpel Person klasse:

offentlig klasse person {privat streng fornavn; privat streng efternavn; privat fødselsdato; // getters og setters}

At konvertere en forekomst af denne klasse til en JSON Snor, først skal vi oprette en forekomst af JsonObjectBuilder og tilføj egenskab / værdipar ved hjælp af tilføje() metode:

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

Bemærk, at tilføje() metoden har et par overbelastede versioner. Det kan modtage de fleste af de primitive typer (såvel som boxed objekter) som sin anden parameter.

Når vi er færdige med at indstille egenskaberne, skal vi bare skrive objektet til et Snor:

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 genererede Snor vil se sådan ud:

{"firstName": "Michael", "lastName": "Scott", "fødselsdato": "06/15/1978"}

2.1. Ved brug af JsonArrayBuilder at bygge arrays

Lad os nu antage, at for at tilføje lidt mere kompleksitet til vores eksempel Person klasse blev ændret for at tilføje en ny egenskab kaldet e-mails som indeholder en liste over e-mail-adresser:

offentlig klasse person {privat streng fornavn; privat streng efternavn; privat fødselsdato; private e-mails på listen; // getters og setters}

For at tilføje alle værdierne fra listen til JsonObjectBuilder vi har brug for hjælp fra JsonArrayBuilder:

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

Bemærk, at vi bruger endnu en overbelastet version af tilføje() metode, der tager en JsonArrayBuilder objekt som dets anden parameter.

Så lad os se på den genererede streng for en Person objekt med to e-mail-adresser:

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

2.2. Formatering af output med PRETTY_PRINTING

Så vi har med succes konverteret et Java-objekt til en gyldig JSON Snor. Lad os nu tilføje nogle enkle formateringer, inden vi går videre til næste afsnit for at gøre output mere “JSON-lignende” og lettere at læse.

I de foregående eksempler oprettede vi en JsonWriter ved hjælp af det enkle Json.createWriter () statisk metode. For at få mere kontrol over det genererede Snor, vi udnytter Java 7'er JsonWriterFactory evne til at oprette en forfatter med en bestemt konfiguration.

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

Koden kan se lidt detaljeret ud, men det gør virkelig ikke meget.

For det første opretter det en forekomst af JsonWriterFactory videregive et konfigurationskort til sin konstruktør. Kortet indeholder kun en post, der angiver sandt til egenskaben PRETTY_PRINTING. Derefter bruger vi den fabriksinstans til at oprette en forfatter i stedet for at bruge Json.createWriter ().

Den nye output vil indeholde de markante linjeskift og tabeller, der kendetegner en JSON Snor:

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

3. Opbygning af Java Objekt Fra en Snor

Lad os nu gøre den modsatte operation: konvertere en JSON Snor ind i et Java-objekt.

Hoveddelen af ​​konverteringsprocessen drejer sig om JsonObject. Brug den statiske metode for at oprette en forekomst af denne klasse Json.createReader () efterfulgt af readObject ():

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

Det createReader () metoden tager en InputStream som en parameter. I dette eksempel bruger vi en StringLæser, da vores JSON er indeholdt i en Snor objekt, men den samme metode kan bruges til at læse indhold fra en fil, for eksempel ved hjælp af FileInputStream.

Med en forekomst af JsonObject ved hånden kan vi læse egenskaberne ved hjælp af getString () metode og tildele de opnåede værdier til en nyoprettet instans af vores Person klasse:

Person person = ny person (); person.setFirstName (jsonObject.getString ("fornavn")); person.setLastName (jsonObject.getString ("sidste navn")); person.setBirthdate (dateFormat.parse (jsonObject.getString ("fødselsdato")));

3.1. Ved brug af JsonArray at få Liste Værdier

Vi bliver nødt til at bruge en speciel klasse, kaldet JsonArray for at udtrække listeværdier fra JsonObject:

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

Det er det! Vi har oprettet en komplet forekomst af Person fra en Json Snor.

4. Forespørgsel efter værdier

Lad os antage, at vi er interesserede i et meget specifikt stykke data, der ligger inde i en JSON Snor.

Overvej JSON nedenfor, der repræsenterer en klient fra en dyrebutik. Lad os sige, at du af en eller anden grund skal få navnet på det tredje kæledyr fra listen over kæledyr:

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

At konvertere hele teksten til et Java-objekt bare for at få en enkelt værdi ville ikke være meget effektivt. Så lad os kontrollere et par strategier for at forespørge JSON Strenge uden at skulle gå igennem hele prøvelsen.

4.1. Forespørgsel ved hjælp af Object Model API

Forespørgsel efter en ejendoms værdi med en kendt placering i JSON-strukturen er ligetil. Vi kan bruge en forekomst af JsonObject, den samme klasse, der blev brugt 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 at navigere igennem jsonObject egenskaber ved hjælp af den korrekte rækkefølge af få*() metoder.

I dette eksempel får vi først en henvisning til "kæledyr" -listen ved hjælp af getJsonArray (), som returnerer en liste med 3 poster. Så bruger vi getJsonObject () metode, der tager et indeks som en parameter, der returnerer et andet JsonObject repræsenterer det tredje punkt på listen. Endelig bruger vi getString () for at få den strengværdi, vi leder efter.

4.2. Forespørgsel ved hjælp af streaming-API

En anden måde at udføre præcise forespørgsler på en JSON på Snor bruger Streaming API, som har JsonParser som hovedklasse.

JsonParser giver ekstremt hurtig, skrivebeskyttet, fremadgang til JS med ulempen ved at være noget mere kompliceret end objektmodellen:

JsonParser jsonParser = Json.createParser (ny StringReader (jsonString)); int-antal = 0; Strengresultat = null; mens (jsonParser.hasNext ()) {Event e = jsonParser.next (); hvis (e == Event.KEY_NAME) {if (jsonParser.getString (). er lig med ("navn")) {jsonParser.next (); hvis (++ count == 3) {result = jsonParser.getString (); pause; }}}}

Dette eksempel leverer det samme resultat som det forrige. Det returnerer navn fra det tredje kæledyr i kæledyr liste.

Engang en JsonParser oprettes ved hjælp af Json.createParser (), er vi nødt til at bruge en iterator (deraf "fremadgang" af JsonParser) for at navigere gennem JSON-tokens, indtil vi kommer til den ejendom (eller egenskaber), vi leder efter.

Hver gang vi går gennem iteratoren, flytter vi til det næste token af ​​JSON-dataene. Så vi skal være omhyggelige med at kontrollere, om det aktuelle token har den forventede type. Dette gøres ved at kontrollere Begivenhed returneret af Næste() opkald.

Der er mange forskellige typer tokens. I dette eksempel er vi interesseret i KEY_NAME typer, der repræsenterer navnet på en ejendom (f.eks. "ejernavn", "kæledyr", "navn", "type"). Når vi trådte gennem en KEY_NAME token med værdien "navn" for tredje gang, vi ved, at det næste token vil indeholde en strengværdi, der repræsenterer navnet på det tredje kæledyr fra listen.

Dette er bestemt sværere end at bruge Object Model API, især for mere komplicerede JSON-strukturer. Valget mellem det ene eller det andet afhænger som altid af det specifikke scenarie, du vil beskæftige dig med.

5. Konklusion

Vi har dækket meget grund på Java EE JSON Processing API med et par enkle eksempler. For at lære andre seje ting om JSON-behandling, se vores serie af Jackson-artikler.

Tjek kildekoden til de klasser, der er brugt i denne artikel, samt nogle enhedstest i vores GitHub-lager.


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