Распарсить 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 шт):
Нашел решение, не уверен, что оно оптимальное, но лучше найти не смог. С помощью генератора классов, сгенерился класс переходник, может кому поможет:
@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");
}
}
}