I have an object like this:
class Test {
List<Integer> a;
}
I want both the following json to be parsed correctly:
{ "a" : "[1, 2, 3]" }
{ "a" : [1, 2, 3] }
When I try to deserialize it in Jackson with the data type as follows, it throws the following exception:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot deserialize value of type `java.util.ArrayList<java.lang.Integer>` from String value (token `JsonToken.VALUE_STRING`)
How can I create a custom deserializer for this case? I’ve already tried creating one like the following, and it doesn’t work and wasn’t called during deserialization, probably because of generic type erasure.
val jackson = ObjectMapper().apply {
registerModule(SimpleModule().addDeserializer(ArrayList::class.java, object : JsonDeserializer<ArrayList<Integer>>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext) =
parser.text.trim('[', ']').split(',').map { it.toInt() } as ArrayList<Integer>
}))
}
2
Answers
Well, I found a solution. If you are ready to use a
JsonNode
, this is possible. Although this code does not involve yourTest
class, maybe you can work on it yourself.Try below mentioned code:
You can comment/uncomment the
enteredJson
and check.EDIT
Here is another solution that involves your
Test
class.And your main class:
For this solution I have passed
Object
into theset
method, you can figure out the rest.I want to provide a solution with a different approach using the class
StdDeserializer
, as I think it would centralize better the unmarshalling logic in a single point, making it more compact, flexible and readable.Firstly, we need to separate the two cases:
Elements as an array
Iterable
from anIterator
of the node’s elements.StreamSupport
class and theIterable.spliterator()
method to stream the elements.int
, and are automatically boxed toInteger
as we have a genericStream<T>
and not anIntStream
.Elements as a String
rootNode.get("a").asText()
.Stream<T>
with the elements.Integer
(and previously removing any white space).List<Integer>
.Implementation
MyDeserializer.java
Test.java
Live Demo
Here is also a live demo at oneCompiler.com