Dinamikus JSON-objektum leképezése Jacksonnal
1. Bemutatkozás
Előre definiált JSON adatstruktúrákkal való munka Jackson-nal egyszerű. Néha azonban kezelnünk kell a dinamikát JSON objektumok, amelyek ismeretlen tulajdonságokkal rendelkeznek.
Ebben a rövid bemutatóban a dinamikus JSON-objektumok Java osztályokba történő leképezésének számos módját láthatjuk.
Vegye figyelembe, hogy az összes tesztnél feltételezzük, hogy van mezőnk objectMapper típusú com.fasterxml.jackson.databind.ObjectMapper.
2. Használata JsonNode
Tegyük fel, hogy a termék specifikációit egy webshopban szeretnénk feldolgozni. Minden terméknek van néhány közös tulajdonsága, de vannak olyanok is, amelyek a termék típusától függenek.
Például meg akarjuk tudni a mobiltelefon kijelzőjének képarányát, de ennek a tulajdonságnak nincs sok értelme egy cipő számára.
Az adatszerkezet így néz ki:
{"name": "Pear yPhone 72", "category": "mobiltelefon", "részletek": {"displayAspectRatio": "97: 3", "audioConnector": "nincs"}}
A dinamikus tulajdonságokat a részletek tárgy.
A következő tulajdonságokkal feltérképezhetjük a közös tulajdonságokat:
osztály Termék {Karakterlánc neve; Vonós kategória; // szabványos mérőeszközök és beállítók}
Ráadásul megfelelő képviseletre van szükségünk a részletek tárgy. Például, com.fasterxml.jackson.databind.JsonNode tudja kezelni a dinamikus kulcsokat.
Ahhoz, hogy használhassuk, mezőként hozzá kell adnunk a sajátunkhoz Termék osztály:
osztály Termék {// közös mezők JsonNode részletek; // szabványos mérőeszközök és beállítók}
Végül ellenőrizzük, hogy működik-e:
Karakterlánc json = ""; Terméktermék = objectMapper.readValue (json, Product.class); assertThat (product.getName ()). isEqualTo ("Körte yPhone 72"); assertThat (product.getDetails (). get ("audioConnector"). asText ()). isEqualTo ("nincs");
Van azonban problémánk ezzel a megoldással. Osztályunk a Jackson könyvtártól függ, mivel van egy JsonNode terület.
3. Használata Térkép
Megoldhatjuk ezt a kérdést a java.util.Térkép a részletek terület. Pontosabban használnunk kell Térkép.
Minden más változhat:
osztály Termék {// közös mezők Térkép részletei; // szabványos mérőeszközök és beállítók}
És akkor egy teszt segítségével ellenőrizhetjük:
Karakterlánc json = ""; Terméktermék = objectMapper.readValue (json, Product.class); assertThat (product.getName ()). isEqualTo ("Körte yPhone 72"); assertThat (product.getDetails (). get ("audioConnector")). isEqualTo ("nincs");
4. Használata @JsonAnySetter
Az előző megoldások akkor jók, ha egy objektum csak dinamikus tulajdonságokat tartalmaz. Néha azonban van fix és dinamikus tulajdonságok keverednek egyetlen JSON objektumban.
Előfordulhat például, hogy le kell simítanunk a termékképünket:
{"name": "Pear yPhone 72", "category": "mobiltelefon", "displayAspectRatio": "97: 3", "audioConnector": "nincs"}
Az ilyen struktúrát dinamikus objektumként kezelhetjük. Sajnos ez azt jelenti, hogy nem tudjuk meghatározni a közös tulajdonságokat - ezeket is dinamikusan kell kezelnünk.
Alternatív megoldásként használhatnánk @JsonAnySetter további, ismeretlen tulajdonságok kezelésére szolgáló módszer megjelölése. Egy ilyen módszernek két érvet kell elfogadnia: a tulajdonság nevét és értékét:
osztály Termék {// közös mezők Térkép részletei = new LinkedHashMap (); @JsonAnySetter void setDetail (Karaktersorozatkulcs, Objektumérték) {details.put (kulcs, érték); } // szokásos mérőeszközök és beállítók}
Ne feledje, hogy a részletek elkerülendő objektum NullPointerExceptions.
Mivel a dinamikus tulajdonságokat a Térkép, ugyanúgy használhatjuk, mint korábban:
Karakterlánc json = ""; Terméktermék = objectMapper.readValue (json, Product.class); assertThat (product.getName ()). isEqualTo ("Körte yPhone 72"); assertThat (product.getDetails (). get ("audioConnector")). isEqualTo ("nincs");
5. Egyéni deserializátor létrehozása
A legtöbb esetben ezek a megoldások nagyon jól működnek. Néha azonban sokkal nagyobb ellenőrzésre van szükségünk. Például tárolhatnánk a JSON-objektumainkkal kapcsolatos deszerializációs információkat egy adatbázisban.
Célozhatjuk ezeket a helyzeteket egy egyedi deserializerrel. Mivel összetett témáról van szó, egy másik cikkben foglalkozunk vele: Kezdő lépések az egyedi deserializációval Jacksonban.
6. Következtetés
Ebben a cikkben a dinamikus JSON-objektumok kezelésének több módját láttuk Jacksonnal.
Szokás szerint a példák elérhetők a GitHub oldalon.