Deserialising different types to single field using Jackson
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}@Testpublic 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);}
What you could is something like this:
@JsonDeserialize(using = ExampleDeserializer.class)public class Example{String prod;Object value; /*this field will takes multiple types*/}
and the ExampleDeserializer would be like this:
public class ExampleDeserializer extends StdDeserializer<Example> { public ExampleDeserializer() { super(Example.class); } public ExampleDeserializer(Class<?> vc) { super(vc); }@Override public Example deserialize(JsonParser p, DeserializationContext ctx) throws IOException { Example ex = new Example(); ObjectCodec mapper = p.getCodec(); if (mapper == null) mapper = new ObjectMapper(); JsonNode tree = mapper.readTree(p); JsonNode internalNode; if (tree.get("prod") != null) { internalNode = tree.get("prod"); prop = internalNode.get("prod").asText(); } if (tree.get("value") != null) { internalNode = tree.get("value"); value = (Double) internalNode.get("value").asDouble() or asText()...; }}
You'll have a slightly easier time of things if you have your different types as different names, so in JSON it should be:
{ prop: "my_map_prop", mapvalue: { "attr1": "value1", "attr2": 12.0 }}
or
{ prop: "my_string_prop", stringvalue: "string"}
If you do it like this you then have more tools at your disposal to enforce validity.