Behandler JSON med Kotlin og Klaxson
1. Oversikt
Klaxon er et av åpen kildekodebibliotek som vi kan bruke til å analysere JSON i Kotlin.
I denne opplæringen skal vi se på funksjonene.
2. Maven avhengighet
Først må vi legge til bibliotekavhengigheten til Maven-prosjektet vårt:
com.beust klaxon 3.0.4
Den siste versjonen finner du på jcenter eller i Spring Plugins Repository.
3. API-funksjoner
Klaxon har fire APIer for å jobbe med JSON-dokumenter. Vi vil utforske disse i de følgende avsnittene.
4. Object Binding API
Med denne APIen, vi kan binde JSON-dokumenter til Kotlin-objekter og omvendt.
For å starte, la oss definere følgende JSON-dokument:
{"name": "HDD"}
Deretter oppretter vi Produkt klasse for binding:
klasse Produkt (val navn: streng)
Nå kan vi teste serieisering:
@Test fun givenProduct_whenSerialize_thenGetJsonString () {val product = Product ("HDD") val result = Klaxon (). ToJsonString (product) assertThat (result) .isEqualTo ("" "{" name ":" HDD "}" "") }
Og vi kan teste deserialisering:
@Test fun givenJsonString_whenDeserialize_thenGetProduct () {val result = Klaxon (). Parse ("" "{" name ":" RAM "}" "") assertThat (result? .Name) .isEqualTo ("RAM")}
Denne API-en støtter også arbeid med dataklasser i tillegg til mutable og uforanderlige klasser.
Klaxon tillater oss det tilpasse kartleggingsprosessen med @Json kommentar. Denne kommentaren har to egenskaper:
- Navn - for å sette et annet navn for feltene
- ignorert - for å ignorere felt i kartleggingsprosessen
La oss lage en CustomProduct klasse for å se hvordan disse fungerer:
class CustomProduct (@Json (name = "productName") val name: String, @Json (ignored = true) val id: Int)
La oss nå bekrefte det med en test:
@Test fun givenCustomProduct_whenSerialize_thenGetJsonString () {val product = CustomProduct ("HDD", 1) val result = Klaxon (). ToJsonString (product) assertThat (result) .isEqualTo ("" "{" productName ":" HDD "}" " ")}
Som vi kan se, er Navn egenskap er seriell som Produktnavn, og id eiendom ignoreres.
5. Streaming API
Med Streaming API kan vi håndtere store JSON-dokumenter ved å lese fra en stream. Denne funksjonen lar koden vår behandle JSON-verdier mens den fremdeles leser.
Vi må bruke JsonLeser klasse fra API for å lese en JSON-strøm. Denne klassen har to spesialfunksjoner for å håndtere streaming:
- beginObject () - sørger for at neste token er begynnelsen på et objekt
- beginArray () - sørger for at neste token er begynnelsen på en matrise
Med disse funksjonene kan vi være sikre på at strømmen er riktig plassert og at den er lukket etter å ha brukt objektet eller matrisen.
La oss teste streaming-API mot en rekke av følgende Produktdata klasse:
dataklasse ProductData (val navn: streng, val kapasitetInGb: Int)
@Test fun givenJsonArray_whenStreaming_thenGetProductArray () {val jsonArray = "" "[{" name ":" HDD "," capacityInGb ": 512}, {" name ":" RAM "," capacityInGb ": 16}]" "" val expectArray = arrayListOf (ProductData ("HDD", 512), ProductData ("RAM", 16)) val klaxon = Klaxon () val productArray = arrayListOf () JsonReader (StringReader (jsonArray)). bruk {reader -> reader.beginArray {while (reader.hasNext ()) {val product = klaxon.parse (reader) productArray.add (product !!)}}} assertThat (productArray) .hasSize (2) .isEqualTo (expectedArray)}
6. JSON Path Query API
Klaxon støtter elementplasseringsfunksjonen fra JSON Path-spesifikasjonen. Med dette API kan vi definere stemmatchere for å finne spesifikke oppføringer i dokumentene våre.
Vær oppmerksom på at også dette API-et streames, og vi får beskjed når et element er funnet og analysert.
Vi må bruke PathMatcher grensesnitt. Dette grensesnittet kalles når JSON-banen fant samsvar med det vanlige uttrykket.
For å bruke dette må vi implementere metodene:
- pathMatches () - returner sant hvis vi vil observere denne veien
- onMatch () - avfyrt når stien er funnet; Vær oppmerksom på at verdien bare kan være en grunnleggende type (f.eks. int, String) og aldri JsonObject eller JsonArray
La oss gjøre en test for å se den i aksjon.
La oss først definere et JSON-lager som en datakilde:
{"inventar": {"disker": [{"type": "HDD", "sizeInGb": 1000}, {"type": "SDD", "sizeInGb": 512}]}}
Nå implementerer vi PathMatcher grensesnitt som følger:
val pathMatcher = object: PathMatcher {override fun pathMatches (path: String) = Pattern.matches (". * beholdning. * disker. * type. *", path) overstyre moro onMatch (path: String, verdi: Enhver) {når (sti) {"$ .inventory.disks [0] .type" -> assertThat (value) .isEqualTo ("HDD") "$ .inventory.disks [1] .type" -> assertThat (value) .isEqualTo ( "SDD")}}}
Merk at vi definerte regexen slik at den samsvarer med typen disk i lagerdokumentet vårt.
Nå er vi klare til å definere testen vår:
@Test fun givenDiskInventory_whenRegexMatches_thenGetTypes () {val jsonString = "" "..." "" val pathMatcher = // ... Klaxon (). PathMatcher (pathMatcher) .parseJsonObject (StringReader (jsonString))}
7. Lavnivå API
Med Klaxon kan vi behandle JSON-dokumenter som en Kart eller a Liste. For å gjøre dette kan vi bruke klassene JsonObject og JsonArray fra API.
La oss gjøre en test for å se JsonObject i aksjon:
@Test-moro gittJsonString_whenParser_thenGetJsonObject () {val jsonString = StringBuilder ("" "{" name ":" HDD "," capacityInGb ": 512," sizeInInch ": 2.5}" "") val parser = Parser () val json = parser .parse (jsonString) som JsonObject hevder at (json) .hasSize (3) .containsEntry ("navn", "HDD") .containsEntry ("capacityInGb", 512) .containsEntry ("sizeInInch", 2.5)}
La oss nå gjøre en test for å se JsonArray funksjonalitet:
@Test moro gittJsonStringArray_whenParser_thenGetJsonArray () {val jsonString = StringBuilder ("" "[{" name ":" SDD "}, {" madeIn ":" Taiwan "}, {" warrantyInYears ": 5}]" "") val parser = Parser () val json = parser.parse (jsonString) som JsonArray hevder mykt ({softly -> softly.assertThat (json) .hasSize (3) softly.assertThat (json [0] ["name"]). IsEqualTo (" SDD ") softly.assertThat (json [1] [" madeIn "]). IsEqualTo (" Taiwan ") softly.assertThat (json [2] [" warrantyInYears "]). IsEqualTo (5)})}
Som vi kan se i begge tilfeller, gjorde vi konverteringene uten definisjon av spesifikke klasser.
8. Konklusjon
I denne artikkelen utforsket vi Klaxon-biblioteket og dets API-er for å håndtere JSON-dokumenter.
Som alltid er kildekoden tilgjengelig på Github.