I am serializing and deserializing following domain object to JSON using Jackson 1.8.3
public class Node {
private String key;
private Object value;
private List<Node> children = new ArrayList<Node>();
/* getters and setters omitted for brevity */
}
Object is then serialized and deserialized using following code
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(destination, rootNode);
And then later deserialized with
mapper.readValue(destination, Node.class);
The original values of the object are either Strings, Doubles, Longs or Booleans. However, during serialization and deserialization Jackson transforms Long values (such as 4) to Integers.
How can I "force" Jackson to deserialize numeric non-decimal values to Long instead of Integer?
I ended up creating a custom deserializer, since in my application logic there are only four different types for values (
Double
,Long
,Integer
andString
).I'm not sure if this is the best possible solution but it works for now.
In my case I did not want to use DeserializationFeature.USE_LONG_FOR_INTS for ObjectMapper, because it would affect all the project. I used the next solution: use a custom deserializer:
And add it to the field of type Object: public class SomeTOWithObjectField {
And it deserialized integers as longs, but other types like String, boolean, double etc. were deserialized as they should be by default.
If you want to wrap a primitive into specific class, you can do follow (example in Kotlin):
And now, your
Int
primitives will be parsed into Age class and vice versa - Age class into Int primitive.If type is declared as java.lang.Object, Jackson uses 'natural' mapping which uses Integer if value fits in 32 bits. Aside from custom handlers you would have to force inclusion of type information (either by adding @JsonTypeInfo next to field / getter; or by enabling so-called "default typing").
In jackson 2 we can use TypeReference to specify the generic type in detail. There is and overloaded method for
readValue()
which takes the TypeReference as the 2nd parameter:If you want to get a list of
Long
instead ofInteger
, you can do the following.This works for maps as well:
In your case, you can convert your class to a generic one. i.e
Node<T>
. When creating nodes, do asNode<String/Integer/etc>
And use the type reference to read the value.There is a new feature in Jackson 2.6 specifically for this case:
configure the ObjectMapper to use
DeserializationFeature.USE_LONG_FOR_INTS
see https://github.com/FasterXML/jackson-databind/issues/504