I have a following class that I want to use for deserializing JSON
public interface MyObject {
@JsonProperty("prop")
String prop;
@JsonProperty("value")
Double value(); // Need this to be either a double or a string or a Map
}
However, I want to be able to parse both the JSON with a double value
{
prop: "myprop",
value: 15.7
}
and a JSON with non Double value like a string or a map
{
prop: "myprop1",
value: {
"attr1": "value1",
"attr2": 12.0
}
}
I looked at @JsonSubTypes
annotation, but that looks like only useful for the cases where inheritance is involved. Is it possible to do it in Jackson? If so how can I define my Java class to achieve the same?
In general, I'd discourage the use of arbitrary types of data points. Having strong types gives plenty of benefits about which I can talk if you want. However, since you only talked about deserialization it might be that you are just reading such a JSON produced by someone else.
The solution is quite simply: use Object field.
public static class MyObject {
@JsonProperty("prop")
String prop;
@JsonProperty("value")
Object value; // <- object
}
@Test
public void testUnknownType() throws JsonProcessingException {
final ObjectMapper objectMapper = new ObjectMapper();
final MyObject object1 = objectMapper.readValue("{\n" +
" \"prop\": \"myprop\",\n" +
" \"value\": 15.7\n" +
"}", MyObject.class);
Assert.assertEquals(15.7d, object1.value);
final MyObject object2 = objectMapper.readValue("{\n" +
" \"prop\": \"myprop1\",\n" +
" \"value\": {\n" +
" \"attr1\": \"value1\",\n" +
" \"attr2\": 12.0\n" +
" }\n" +
"}", MyObject.class);
Assert.assertTrue(object2.value instanceof Map);
}