I have a problem with deserialization of the JSON using Jackson in my rest-assured tests. In my JSON I have a key "value" that can be an array of Strings or object like Boolean.
{
"value": ["value1", "value2"]
}
or
{
"value": 2272204.2426
}
So I wrote custom deserializer for this field:
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
if (node.isArray()) {
List<String> list = new ArrayList<>();
for (JsonNode elementNode : node) {
list.add(oc.treeToValue(elementNode, String.class));
}
return list;
} else {
if(node.isDouble()) {
return oc.treeToValue(node, Double.class);
}
else if(node.isBoolean()){
return oc.treeToValue(node, Boolean.class);
}
else {
return oc.treeToValue(node, String.class);
}
}
}
In the end I've noticed that numeric value like 2272204.2426 is deserialized to 2272204.2 I tried to desierialize it using Gson and it works well. Do you have any idea why using Jackson there is lack of decimal part? I've tried to debug the code and I've noticed that on this step JsonNode node = oc.readTree(jp); the value is 2272204.2
Why not use ObjectMapper
from Jackson? You can add DeserializationFeature
to it unlike ObjectCodec
. Mapper is actually extending Codec, but with more features that you need in this case.
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
JsonNode node = //node where the value is defined as Double
Double value = null;
try {
value = mapper.treeToValue(node, Double.class);
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println(value);
Use the above logic in your node.isDouble()
case