Распарсить json, который может возвращать разные типы полей с одинаковым названием

Прошу помощи с парсингом json. Ситуация следующая, в зависимости от результата обработки запроса возвращается разный json, при успехе он содержит массив объектов ResultResult[], а при провале объект типа ErrorResult, название у поля result. Если бы названия были разные, то свойства NON_NULL хватило бы, но в данном случае, естественно не подходит, т.к. одинаковые названия полей вызывают экскпшн:

com.fasterxml.jackson.databind.JsonMappingException: Conflicting setter definitions for property "result"

Подскажите что можно сделать с классом для корректного маппинга. Сам класс ResponseResult хранится в середине иерархии json и сам так же находится в массиве.

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult {
    private long status;
    private Query query;
    private ResultResult[] result;
    private ErrorResult errorResult;

    @JsonProperty("status")
    public long getStatus() { return status; }

    @JsonProperty("status")
    public void setStatus(long value) { this.status = value; }

    @JsonProperty("query")
    public Query getQuery() { return query; }

    @JsonProperty("query")
    public void setQuery(Query value) { this.query = value; }

    @JsonProperty("result")
    public ResultResult[] getResult() { return null; }

    @JsonProperty("result")
    public void setResult(ResultResult[] value) { this.result = value; }

    @JsonProperty("result")
    public ErrorResult getErrorResult() {
        return errorResult;
    }

    @JsonProperty("result")
    public void setErrorResult(ErrorResult errorResult) {
        this.errorResult = errorResult;
    }
}

Ответы (1 шт):

Автор решения: Dilitand

Нашел решение, не уверен, что оно оптимальное, но лучше найти не смог. С помощью генератора классов, сгенерился класс переходник, может кому поможет:

@JsonDeserialize(using = ResultUnion.Deserializer.class)
@JsonSerialize(using = ResultUnion.Serializer.class)
public class ResultUnion {
    public PurpleResult[] purpleResultArrayValue;
    public FluffyResult fluffyResultValue;

    static class Deserializer extends JsonDeserializer<ResultUnion> {
        @Override
        public ResultUnion deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            ResultUnion value = new ResultUnion();
            switch (jsonParser.getCurrentToken()) {
            case START_ARRAY:
                value.purpleResultArrayValue = jsonParser.readValueAs(PurpleResult[].class);
                break;
            case START_OBJECT:
                value.fluffyResultValue = jsonParser.readValueAs(FluffyResult.class);
                break;
            default: throw new IOException("Cannot deserialize ResultUnion");
            }
            return value;
        }
    }

    static class Serializer extends JsonSerializer<ResultUnion> {
        @Override
        public void serialize(ResultUnion obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (obj.purpleResultArrayValue != null) {
                jsonGenerator.writeObject(obj.purpleResultArrayValue);
                return;
            }
            if (obj.fluffyResultValue != null) {
                jsonGenerator.writeObject(obj.fluffyResultValue);
                return;
            }
            throw new IOException("ResultUnion must not be null");
        }
    }
}
→ Ссылка