Jackson kivételek - problémák és megoldások

1. Áttekintés

Ebben az oktatóanyagban áttekintjük a leggyakoribb Jackson-kivételek - a JsonMappingException és UnrecognizedPropertyException.

Végül - röviden átbeszéljük Jacksont, hogy nincs ilyen módszerhiba.

2. “JsonMappingException: Nem lehet megépíteni a

2.1. A probléma

Először - vessünk egy pillantást a Jsonmappingexception: Can Construct példányára.

Ezt a kivételt akkor dobják meg, ha Jackson nem hozhat létre példányt az osztályból - ez akkor történik, ha az osztály van absztrakt vagy csak egy felület.

A következő példában - megpróbálunk deserializálni egy példányt az osztályból Állatkert amelynek van tulajdonsága állat val vel absztrakt típus Állat:

közosztályú állatkert {nyilvános állatállat; public Zoo () {}} absztrakt osztály Animal {public String name; public Animal () {}} osztály Cat meghosszabbítja az Animal {public int életét; nyilvános macska () {}}

Amikor megpróbálunk deszerializálni egy JSON-t Húr az állatkert-példányba dobja a „Jsonmappingexception: Nem lehet megépíteni az

@Test (várható = JsonMappingException.class) public void givenAbstractClass_whenDeserializing_thenException () dobja az IOException {String json = "{" animal ": {" name ":" csipkés "}}"; ObjectMapper mapper = új ObjectMapper (); mapper.reader (). forType (Zoo.class) .readValue (json); }

A teljes kivétel az:

com.fasterxml.jackson.databind.JsonMappingException: Nem lehet létrehozni az org.baeldung.jackson.exception példányát. Állat, probléma: az absztrakt típusokat vagy konkrét típusokhoz kell hozzárendelni, egyéni deserializátorral kell ellátni őket, vagy további típusú információkkal kell példázni a következő címen: [Forrás: {"animal": {"name": "csipkés"}}; sor: 1, oszlop: 2] (hivatkozási láncon keresztül: org.baeldung.jackson.exception.Zoo ["állat"]) itt: c.f.j.d.JsonMappingException.from (JsonMappingException.java:148)

2.2. Megoldások

Egy egyszerű feljegyzéssel megoldhatjuk a problémát - @JsonDeserialize az absztrakt osztályon:

@JsonDeserialize (as = Cat.class) absztrakt osztály Animal {...}

Ha az absztrakt osztálynak egynél több altípusa van, akkor fontolóra kell vennünk az altípusra vonatkozó információk beillesztését, amint az ebben a bejegyzésben látható: Öröklés Jacksonnal.

3. JsonMappingException: Nincs megfelelő kivitelező

3.1. A probléma

Most - nézzük meg a Jsonmappingexception: Nincs megfelelő konstrukciót típusra talált.

Ezt a kivételt akkor dobják meg, ha Jackson nem fér hozzá a kivitelezőhöz.

A következő példában - osztály Felhasználó nincs alapértelmezett konstruktora:

public class Felhasználó {public int id; public String név; public Felhasználó (int id, String név) {this.id = id; ez.név = név; }}

Amikor megpróbálunk deszerializálni egy JSON karakterláncot a felhasználó számára, a „Jsonmappingexception: Nem található megfelelő konstruktor található” felirat dobódik - ahogy a következő példában:

@Test (várható = JsonMappingException.class) public void givenNoDefaultConstructor_whenDeserializing_thenException () dobja az IOException {String json = "{" id ": 1," name ":" John "}"; ObjectMapper mapper = új ObjectMapper (); mapper.reader (). forType (Felhasználó.osztály) .readValue (json); }

A teljes kivétel az:

com.fasterxml.jackson.databind.JsonMappingException: Nem található megfelelő kivitelező az [egyszerű típus, osztály org.baeldung.jackson.exception.User] típushoz: nem lehet példányosítani a JSON objektumból (a típusinformáció hozzáadása / engedélyezése szükséges?) a [ Forrás: {"id": 1, "name": "John"}; sor: 1, oszlop: 2] itt: c.f.j.d. JsonMappingException.from (JsonMappingException.java:148)

3.2. A megoldás

A probléma megoldásához egyszerűen adjon hozzá egy alapértelmezett konstruktort a következő példa szerint:

public class Felhasználó {public int id; public String név; public User () {super (); } public Felhasználó (int id, String name) {this.id = id; ez.név = név; }}

Most, amikor deszerializálódunk - a folyamat remekül fog működni:

@Test public void givenDefaultConstructor_whenDeserializing_thenCorrect () dobja az IOException {String json = "{" id ": 1," name ":" John "}"; ObjectMapper mapper = új ObjectMapper (); Felhasználói felhasználó = mapper.reader () .forType (Felhasználó.osztály) .readValue (json); assertEquals ("John", felhasználónév); }

4. JsonMappingException: A gyökérnév nem felel meg a vártnak

4.1. A probléma

Következő - vessünk egy pillantást a Jsonmappingexception oldalra: A gyökérnév nem felel meg a vártnak

Ezt a kivételt akkor dobják meg, ha a JSON nem egyezik meg pontosan azzal, amit Jackson keres; például a fő JSON-t a következő példa szerint lehet becsomagolni:

@Test (várható = JsonMappingException.class) public void givenWrappedJsonString_whenDeserializing_thenException () dobja az IOException {String json = "{" user ": {" id ": 1," name ":" John "}}"; ObjectMapper mapper = új ObjectMapper (); mapper.enable (DeserializationFeature.UNWRAP_ROOT_VALUE); mapper.reader (). forType (Felhasználó.osztály) .readValue (json); }

A teljes kivétel az:

com.fasterxml.jackson.databind.JsonMappingException: A 'user' gyökérnév nem egyezik a várt ('User') névvel az [simple type, class org.baeldung.jackson.dtos.User] típusnál a [Source: {"user": {"id": 1, "név": "John"}}; sor: 1, oszlop: 2] itt: c.f.j.d. JsonMappingException.from (JsonMappingException.java:148) 

4.2. A megoldás

Megoldhatjuk ezt a problémát az annotáció segítségével @JsonRootName - mint a következő példában:

@JsonRootName (value = "user") public class UserWithRoot {public int id; public String név; }

Amikor megpróbáljuk deserializálni a bebugyolált JSON-ot - ez helyesen működik:

@Test public void givenWrappedJsonStringAndConfigureClass_whenDeserializing_thenCorrect () dobja az IOException {String json = "{" user ": {" id ": 1," name ":" John "}}"; ObjectMapper mapper = új ObjectMapper (); mapper.enable (DeserializationFeature.UNWRAP_ROOT_VALUE); UserWithRoot user = mapper.reader () .forType (UserWithRoot.class) .readValue (json); assertEquals ("John", felhasználónév); }

5. JsonMappingException: Nem található Serializer az osztályhoz

5.1. A probléma

Most - vessünk egy pillantást a Jsonmappingexception: Nem található Serializer osztályra.

Ezt a kivételt akkor dobják meg, ha megpróbálja Sorosítson egy példányt, miközben a tulajdonságai és az összesítőik privátak.

A következő példában - megpróbálunk egy „UserWithPrivateFields“:

public class UserWithPrivateFields {int id; Karakterlánc neve; }

Amikor megpróbáljuk sorosítani aUserWithPrivateFields”- a„ Jsonmappingexception: Nem található sorosító az osztályhoz ”kivétel a következő példában szerepel:

@Test (várható = JsonMappingException.class) public void givenClassWithPrivateFields_whenSerializing_thenException () dobja az IOException {UserWithPrivateFields user = new UserWithPrivateFields (1, "John"); ObjectMapper mapper = új ObjectMapper (); mapper.writer (). writeValueAsString (felhasználó); }

A teljes kivétel:

com.fasterxml.jackson.databind.JsonMappingException: Nem található sorosító a (z) org.baeldung.jackson.exception.UserWithPrivateFields osztályhoz, és a BeanSerializer létrehozásához nem találtak tulajdonságokat (a kivétel elkerülése érdekében tiltsa le a SerializationFeature.FAIL_ON_EMPTY_fájlokat. failForEmpty (UnknownSerializer.java:59)

5.2. A megoldás

Megoldhatjuk ezt a problémát a ObjectMapper láthatóság - mint a következő példában:

@Test public void givenClassWithPrivateFields_whenConfigureSerializing_thenCorrect () dobja az IOException {UserWithPrivateFields felhasználó = new UserWithPrivateFields (1, "John"); ObjectMapper mapper = új ObjectMapper (); mapper.setVisibility (PropertyAccessor.FIELD, Visibility.ANY); Karakterlánc eredménye = mapper.writer (). WriteValueAsString (felhasználó); assertThat (eredmény, tartalmazzaString ("John")); }

Vagy az annotáció használatával @JsonAutoDetect - mint a következő példában:

@JsonAutoDetect (fieldVisibility = Visibility.ANY) public class UserWithPrivateFields {...}

Természetesen, ha van lehetőségünk módosítani az osztály forrását, akkor hozzáadhatunk gettert is Jackson számára.

6. JsonMappingException: Nem deserializálhatom a

6.1. A probléma

Következő - vessünk egy pillantást a Jsonmappingexception: Nem lehet deserializálni a.

Ezt a kivételt akkor dobják meg, ha rossz típust használnak miközben deserializált.

A következő példában - megpróbáljuk deserializálni a Lista nak,-nek Felhasználó:

@Test (várható = JsonMappingException.class) public void givenJsonOfArray_whenDeserializing_thenException () dobja JsonProcessingException, IOException {String json = "[{" id ": 1," name ":" John "}, {" id ": 2, :"Ádám"}]"; ObjectMapper mapper = új ObjectMapper (); mapper.reader (). forType (Felhasználó.osztály) .readValue (json); }

A teljes kivétel az:

com.fasterxml.jackson.databind.JsonMappingException: Nem lehet deserializálni az org.baeldung.jackson.dtos.User példányát a START_ARRAY tokenből a [Forrás: [{"id": 1, "név": "John"}, { "id": 2, "név": "Ádám"}]; sor: 1, oszlop: 1] itt: c.f.j.d. JsonMappingException.from (JsonMappingException.java:148)

6.2. A megoldás

Megoldhatjuk ezt a problémát a típus megváltoztatásával Felhasználó nak nek Lista - mint a következő példában:

@Test public void givenJsonOfArray_whenDeserializing_thenCorrect () dobja a JsonProcessingException, IOException {String json = "[{" id ": 1," name ":" John "}, {" id ": 2," name ":" Adam "}]" " ; ObjectMapper mapper = új ObjectMapper (); List users = mapper.reader () .forType (új TypeReference() {}) .readValue (json); assertEquals (2, users.size ()); }

7. UnrecognizedPropertyException

7.1. A probléma

Most - nézzük meg a UnrecognizedPropertyException.

Ezt a kivételt akkor dobják meg, ha van ismeretlen tulajdonság a JSON-ban Húr, miközben deserializál.

A következő példában - megpróbálunk egy JSON karakterláncot deszerializálni extra tulajdonsággal “ellenőrzött“:

@Test (várható = UnrecognizedPropertyException.class) public void givenJsonStringWithExtra_whenDeserializing_thenException () dobja az IOException {String json = "{" id ": 1," név ":" John "," bejelölt ": igaz}"; ObjectMapper mapper = új ObjectMapper (); mapper.reader (). forType (Felhasználó.osztály) .readValue (json); }

A teljes kivétel az:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Ismeretlen mező "bejelölve" (class org.baeldung.jackson.dtos.User), nincs jelölve tudhatatlannak (2 ismert tulajdonság: "id", "név"]) a [ Forrás: {"id": 1, "név": "John", "bejelölt": igaz}; sor: 1, oszlop: 38] (hivatkozási láncon keresztül: org.baeldung.jackson.dtos.User ["bejelölve"]) a c.f.j.d.exc.UnrecognizedPropertyException.from (UnrecognizedPropertyException.java:51) címen

7.2. A megoldás

Megoldhatjuk ezt a problémát a ObjectMapper - mint a következő példában:

@Test public void givenJsonStringWithExtra_whenConfigureDeserializing_thenCorrect () dobja az IOException {String json = "{" id ": 1," name ":" John "," check ": true}"; ObjectMapper mapper = új ObjectMapper (); mapper.disable (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); Felhasználói felhasználó = mapper.reader (). ForType (Felhasználó.osztály) .readValue (json); assertEquals ("John", felhasználónév); }

Vagy használhatjuk az annotációt @JsonIgnoreProperties:

@JsonIgnoreProperties (ignoreUnknown = true) nyilvános osztály Felhasználó {...}

8. JsonParseException: Váratlan karakter (”” (39. kód))

8.1. A probléma

Következő - beszéljük meg JsonParseException: Váratlan karakter (”” (39-es kód)).

Ezt a kivételt akkor dobják meg, ha a deszerializálandó JSON karakterlánc egyetlen idézőjelet tartalmaz dupla idézőjelek helyett.

A következő példában - megpróbálunk deszerializálni egy idézőjeleket tartalmazó JSON karakterláncot:

@Test (várható = JsonParseException.class) public void givenStringWithSingleQuotes_whenDeserializing_thenException () dobja JsonProcessingException, IOException {String json = "{'id': 1, 'name': 'John'}"; ObjectMapper mapper = új ObjectMapper (); mapper.reader () .forType (Felhasználó.osztály) .readValue (json); }

A teljes kivétel az:

com.fasterxml.jackson.core.JsonParseException: Váratlan karakter ('' '(39-es kód)): kettős idézettel számított arra, hogy a mező nevét a [Forrás: {' id ': 1,' név ':' John '} mezőbe kezdi. ; sor: 1, oszlop: 3] a c.f.j.core.JsonParser._constructError (JsonParser.java:1419)

8.2. A megoldás

Megoldhatjuk ezt a ObjectMapper hogy egyetlen idézetet engedélyezzen:

@Test public void givenStringWithSingleQuotes_whenConfigureDeserializing_thenCorrect () dobja JsonProcessingException, IOException {String json = "{'id': 1, 'name': 'John'}"; JsonFactory gyár = új JsonFactory (); factory.enable (JsonParser.Feature.ALLOW_SINGLE_QUOTES); ObjectMapper mapper = új ObjectMapper (gyári); Felhasználói felhasználó = mapper.reader (). ForType (Felhasználó.osztály) .readValue (json); assertEquals ("John", felhasználónév); }

9. Jackson NoSuchMethodError

Végül - beszéljük meg gyorsan a Jackson „Nincs ilyen módszer” hibákat.

Mikor java.lang.NoSuchMethodError Kivételt dobnak, általában azért, mert az osztályterületén több (és inkompatibilis) Jackson edény verziója van.

A teljes kivétel az:

java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonParser.getValueAsString () Ljava / lang / String; itt: c.f.j.d.deser.std.StringDeserializer.deserialize (StringDeserializer.java:24)

10. Következtetés

Ebben a cikkben mélyen belemerültünk a leggyakoribb Jackson-problémák - kivételek és hibák, megvizsgálva az egyes lehetséges okokat és megoldásokat.

Mindezen példák és kódrészletek megvalósítása megtalálható a Githubon - ez egy Maven-alapú projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.


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