我必须使用自定义反序列化器来解析包装类(将其视为Either)。 我能够找出要解析的包含类型的唯一方法是首先使用ObjectMapper.readTree()将json解析为ObjectNode,然后在字段上进行求值。基本上与示例6中的相同:http://programmerbruce.blogspot.se/2011/05/deserialize-json-with-jackson-into.html
我有一种直觉,认为这不是最好的表现,因为我有效地解析了包装类中的部分两次,但听到这样的话会很有趣:
readTree是懒惰还是渴望,这意味着我可以忽略我解析两次的事实?
public class EitherResponseJsonDeserializer extends JsonDeserializer<EitherResponse<IdTypeResponse, ErrorIdTypeResponse>> implements ContextualDeserializer {
protected JavaType successType;
protected JavaType errorType;
@Override
public EitherResponse<IdTypeResponse, ErrorIdTypeResponse> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
ObjectNode root = mapper.readTree(jp);
if(root.get("error") == null){
return new EitherResponse<>((IdTypeResponse) mapper.treeToValue(root, successType.getRawClass()));
}
return new EitherResponse<>((ErrorIdTypeResponse) mapper.treeToValue(root, errorType.getRawClass()));
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
final JavaType contextualType = ctxt.getContextualType();
final JavaType successType = contextualType.containedType(0);
final JavaType errorType = contextualType.containedType(1);
EitherResponseJsonDeserializer deserializer = new EitherResponseJsonDeserializer();
deserializer.successType = successType;
deserializer.errorType = errorType;
return deserializer;
}
}