Let there exist an abstract class A with property a and three non-abstract subclasses B, C and D. B has no additional property, C contains property c and D contains both properties c and d.
I would like subclasses of StdDeserializer for abstract class A to be able to decide based on the existence of deserializable properties which subclass to choose from.
I did this with Codehaus's Jackson release before, and it worked perfectly using the following implementation:
class AbstractADeserializer extends StdDeserializer<A> {
AbstractADeserializer () {
super(A.class);
}
@Override
public A deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
ObjectNode root = (ObjectNode) mapper.readTree(jp);
Class<? extends A> requestClass = null;
JsonNode cValue = root.findValue("c");
JsonNode dValue = root.findValue("d");
logger.debug(Boolean.toString(c != null));
logger.debug(Boolean.toString(d != null));
if(c != null && d == null) {
logger.debug("Found C");
requestClass = C.class;
} else if(c != null && d != null) {
logger.debug("Found D");
requestClass = D.class;
} else {
logger.debug("Found B");
requestClass = B.class;
}
return mapper.readValue(root, requestClass);
}
}
This worked fine, but after switching to Jackson 2.4 from FasterXML, ObjectMapper does not allow ObjectNode as a parameter to the method readValue.
return mapper.readValue(jp, requestClass);
com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
at [Source: org.apache.catalina.connector.CoyoteInputStream@1286ec89; line: 1, column: 559]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3095)
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3009)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1637)
, ? JsonParser, .