Deserialize list of array failed with enableDefaultTyping
See original GitHub issueI use the same ObjectMapper instance to serialize and deserialize List<String[]>
, deserialization failed with all of DefaultTyping’s, and same as List<Integer[]>
, tested with the latest version 2.9.6.
ObjectMapper objectMapper = new ObjectMapper();
objectMapper = objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT,
JsonTypeInfo.As.PROPERTY);
List<String[]> list = new ArrayList<>();
list.add(new String[] { "test" });
String s = objectMapper.writeValueAsString(list); // [["[Ljava.lang.String;",["test"]]]
List<String[]> list2 = objectMapper.readValue(s, new TypeReference<List<String[]>>() {
});
System.out.println(Arrays.equals(list.get(0), list2.get(0)));
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token
at [Source: (String)"[["[Ljava.lang.String;",["test"]]]"; line: 1, column: 25] (through reference chain: java.util.ArrayList[0]->java.lang.Object[][1])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1138)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1092)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseString(StdDeserializer.java:569)
at com.fasterxml.jackson.databind.deser.std.StringArrayDeserializer.deserialize(StringArrayDeserializer.java:157)
at com.fasterxml.jackson.databind.deser.std.StringArrayDeserializer.deserialize(StringArrayDeserializer.java:21)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3023)
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (4 by maintainers)
Top Results From Across the Web
Deserializing Java arrays with Jackson - json - Stack Overflow
The best solution I've found for now is checking before serialization if the object is an array (Class.isArray) and then doing the ...
Read more >cannot deserialize out of start_array token - You.com
Im trying to deserialize a JSON list into a custom class with a list-typed parameter. However, this fails with com.fasterxml.jackson.databind.exc.
Read more >Inheritance in Jackson | Baeldung
This tutorial will demonstrate how to handle inclusion of subtype metadata and ignoring properties inherited from superclasses with Jackson.
Read more >Failed to deserialize JSON - OutSystems
The error is correct, the built-in JSON deserializer does not allow you to turn an array of simple types into an Object. You...
Read more >Jackson Deserialization Vulnerabilities - NCC Group
The enableDefaultTyping method instructs ObjectMapper to include the Java class names for all non- final classes using the default inclusion ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I think the problem is Java Type Erasure with root values: you are serializing something only seen as
List<?>
(due type erasure), and type information is included for elements as they are nominally of typeObject (type information checks always use static type, not runtime type). But when reading back you are instructing type to be
List<String>` , and thereby entries are not expected to have type information.In general I would strongly recommend against using generic types like
List<X>
as root values; and instead use a POJO as wrapper. This avoid most if not all type erasure issues.If you do want combination to work without changes, however, you will need to force type on serialization. Something like
or create a non-generic List type:
and use that instead of generic version. This will also work around type erasure.
Actually the flaw here is call for deserialization: it must use same type information as serialization, to determine proper base type. Specifically, it should NOT try to pass type as
List<String[]>
since that is not type serializer has access to: due to Java Type Erasure, all it knows is type isList<?>
.So: either writeValue() call has to also pass more specific type information (via
mapper.writerFor(new TypeReference<....>
) orreadValue()
should be given less accurate one.And note that the reason your change also works is that as per configuration, ONLY nominal type of
Object
will get type information added;Object[]
is notObject
(nor isString[]
). There are otherDefaultTyping
options (likeOBJECT_AND_NON_CONCRETE
andNON_FINAL
) that could work better as well.At any rate functionality works as I would expect so I will close the issue.