Kartlegge et dynamisk JSON-objekt med Jackson

1. Introduksjon

Å jobbe med forhåndsdefinerte JSON-datastrukturer med Jackson er grei. Noen ganger trenger vi imidlertid å håndtere dynamikk JSON-objekter, som har ukjente egenskaper.

I denne korte opplæringen ser vi flere måter å kartlegge dynamiske JSON-objekter i Java-klasser.

Merk at vi i alle testene antar at vi har et felt objectMapper av typen com.fasterxml.jackson.databind.ObjectMapper.

2. Bruke JsonNode

La oss si at vi vil behandle produktspesifikasjoner i en nettbutikk. Alle produktene har noen vanlige egenskaper, men det er andre, som avhenger av produkttypen.

For eksempel vil vi vite størrelsesforholdet til skjermen på en mobiltelefon, men denne egenskapen gir ikke mye mening for en sko.

Datastrukturen ser slik ut:

{"name": "Pear yPhone 72", "category": "cellphone", "details": {"displayAspectRatio": "97: 3", "audioConnector": "none"}}

Vi lagrer de dynamiske egenskapene i detaljer gjenstand.

Vi kan kartlegge de vanlige egenskapene med følgende Java-klasse:

klasse Produkt {Strengnavn; Strengkategori; // standard getters og setters}

På toppen av det trenger vi en passende representasjon for detaljer gjenstand. For eksempel, com.fasterxml.jackson.databind.JsonNode kan håndtere dynamiske nøkler.

For å bruke den, må vi legge den til som et felt i vårt Produkt klasse:

klasse Produkt {// vanlige felt JsonNode detaljer; // standard getters og setters}

Til slutt bekrefter vi at det fungerer:

String json = ""; Produktprodukt = objectMapper.readValue (json, Product.class); assertThat (product.getName ()). isEqualTo ("Pear yPhone 72"); assertThat (product.getDetails (). get ("audioConnector"). asText ()). isEqualTo ("none");

Vi har imidlertid et problem med denne løsningen. Klassen vår er avhengig av Jackson-biblioteket siden vi har en JsonNode felt.

3. Bruke Kart

Vi kan løse dette problemet ved å bruke java.util.Kart for detaljer felt. Mer presist, vi må bruke Kart.

Alt annet kan være det samme:

klasse Produkt {// vanlige felt Kartdetaljer; // standard getters og setters}

Og så kan vi bekrefte det med en test:

String json = ""; Produktprodukt = objectMapper.readValue (json, Product.class); assertThat (product.getName ()). isEqualTo ("Pear yPhone 72"); assertThat (product.getDetails (). get ("audioConnector")). isEqualTo ("none");

4. Bruke @JsonAnySetter

De tidligere løsningene er gode når et objekt bare inneholder dynamiske egenskaper. Noen ganger har vi imidlertid gjort det faste og dynamiske egenskaper blandet i et enkelt JSON-objekt.

For eksempel kan det hende at vi må flate produktrepresentasjonen vår:

{"name": "Pear yPhone 72", "category": "cellphone", "displayAspectRatio": "97: 3", "audioConnector": "none"}

Vi kan behandle en struktur som dette som et dynamisk objekt. Dessverre betyr det at vi ikke kan definere vanlige egenskaper - vi må også behandle dem dynamisk.

Alternativt kan vi bruke @JsonAnySetter for å merke en metode for håndtering av ekstra, ukjente egenskaper. En slik metode bør akseptere to argumenter: navnet og verdien på eiendommen:

klasse Produkt {// vanlige felt Kartdetaljer = ny LinkedHashMap (); @JsonAnySetter ugyldig setDetail (strengnøkkel, objektverdi) {details.put (nøkkel, verdi); } // standard getters and setters}

Merk at vi må instansiere detaljer objekt å unngå NullPointerExceptions.

Siden vi lagrer de dynamiske egenskapene i en Kart, kan vi bruke det på samme måte som før:

String json = ""; Produktprodukt = objectMapper.readValue (json, Product.class); assertThat (product.getName ()). isEqualTo ("Pear yPhone 72"); assertThat (product.getDetails (). get ("audioConnector")). isEqualTo ("none");

5. Lage en tilpasset deserializer

I de fleste tilfeller fungerer disse løsningene helt fint. Noen ganger trenger vi imidlertid mye mer kontroll. For eksempel kan vi lagre deserialiseringsinformasjon om JSON-objektene våre i en database.

Vi kan målrette disse situasjonene med en tilpasset deserializer. Siden det er et komplekst tema, dekker vi det i en annen artikkel, og kommer i gang med tilpasset deserialisering i Jackson.

6. Konklusjon

I denne artikkelen så vi flere måter å håndtere dynamiske JSON-objekter med Jackson på.

Som vanlig er eksemplene tilgjengelige på GitHub.


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