I have a class hierarchy similar to this one:
public static class BaseConfiguration {
}
public abstract class Base {
private BaseConfiguration configurati
I had to do something similar, and ended up creating a generic polymorphic list serializer and deserialzer. Here is the deserialize that I think will work for you:
public class PolymorphicListDeserializer extends JsonDeserializer> implements ContextualDeserializer {
private HashMap _typeMap = null;
private Class _elementType;
private static List getNewList(Class clazz) {
return new ArrayList();
}
@Override
public List> deserialize(final JsonParser jp, DeserializationContext ctxt) throws IOException {
final List list = getNewList(_elementType);
JsonToken nextToken = jp.getCurrentToken();
if (nextToken == JsonToken.START_OBJECT) {
if ( _typeMap.containsKey( currentFieldName )) {
list.add( _elementType.cast( ctxt.readValue( jp, _typeMap.get( currentFieldName ) ) ) );
}
nextToken = jp.nextToken();
} else if (currentFieldName != null && isEndToken(nextToken) && wrapperCount == 0) {
break;
} else {
nextToken = jp.nextToken();
}
}
return list;
}
public JsonDeserializer> createContextual( DeserializationContext ctxt, BeanProperty property ) throws JsonMappingException {
//In Jackson 2.6.3, this method is called once per instance and the exception is never thrown
if ( _typeMap == null )
_typeMap = new HashMap();
else
throw new RuntimeException("Unsupported version of Jackson. Code assumes context is created once and only once.");
_elementType = property.getType().getContentType().getRawClass();
//For now, requiring XmlElements annotation to work. May add support for JsonElements (if needed) later.
for (XmlElement e : property.getAnnotation(XmlElements.class).value()) {
_typeMap.put(e.name(), e.type());
}
return this;
}
private static boolean isStartToken(JsonToken t) {
boolean result = false;
if (t == JsonToken.START_OBJECT) {
result = true;
} else if (t == JsonToken.START_ARRAY) {
result = true;
}
return result;
}