Я получаю документы JSON от стороннего инструмента, который находится в стадии разработки, то есть JSON часто расширяется.Я хотел бы придерживаться простейшего механизма десериализации, чтобы избежать увеличения обслуживания, которое идет с пользовательскими десериализаторами.
Вот соответствующая часть JSON:
{
"key1": "value1",
"key2": "value2",
"variants": {
"columns": ["chr", "pos", "id", "ref", "alt", "qual", "filter", "type", "genotype", "alignpos", "basepos", "signalpos"],
"rows": [
["17", 19561093, ".", "G", "C", 51, "PASS", "SNV", "het.", 97, 147, 1761],
["17", 19561123, ".", "T", "G", 51, "PASS", "SNV", "het.", 127, 177, 2120],
["17", 19561149, ".", "G", "A", 51, "PASS", "SNV", "het.", 153, 203, 2432]],
"xranges": [
[829, 1129],
[1480, 1780],
[1492, 1792]],
}}
Проблема заключается вВариант тега, в частности, с «строк».Похоже, что «строки» были сериализованы с аннотацией @JsonValue, чтобы избавиться от имен полей, которые в противном случае были бы частью каждой «строки».Вместо этого было дополнительно сериализовано дополнительное поле «столбцы», чтобы хотя бы раз упомянуть имена столбцов.
Без тега вариантов я успешно десериализовал JSON в POJO с использованием ObjectMapper:
public class Pojo {
private String key1;
private String key2;
public String getKey1() {
return key1;
}
public void setKey1(String key1) {
this.key1 = key1;
}
public String getKey2() {
return key2;
}
public void setKey2(String key2) {
this.key2 = key2;
}
}
и
public static void main(String[] args) {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Pojo pojo = objectMapper.readValue(jsonFile, Pojo.class);
}
Теперь, чтобы десериализовать варианты, я добавил это к своему исходному POJO
@JsonProperty("variants")
private PojoVariants pojoVariants;
Затем реализовал PojoVariants
public class PojoVariants {
@JsonProperty("columns")
private String[] columnNames;
@JsonProperty("rows")
private PojoVariant[] pojoVariantArr;
public String[] getColumnNames() {
return columnNames;
}
public void setColumnNames(String[] columnNames) {
this.columnNames = columnNames;
}
public PojoVariant[] getPojoVariantArr() {
return pojoVariantArr;
}
public void setPojoVariantArr(PojoVariant[] pojoVariantArr) {
this.pojoVariantArr = pojoVariantArr;
}
}
и, наконец, PojoVariant
@JsonPropertyOrder({
"chr", "pos",
"id", "ref", "alt",
"quality", "filter", "type", "genotype",
"alignPos", "basePos", "signalPos" })
public class PojoVariant {
private String chr;
private int pos;
private String id;
private String ref;
private String alt;
private int quality;
private String filter;
private String type;
private String genotype;
private int alignPos;
private int basePos;
private int signalPos;
@JsonCreator
public PojoVariant(
String chr, int pos,
String id, String ref, String alt,
int quality, String filter, String type, String genotype,
int alignPos, int basePos, int signalPos) {
}
}
Устанавливая @JsonPropertyOrder, я надеялся, что Джексон сможет выяснить, что я хотел бы прочитать каждую «строку» в экземпляр PojoVariant.Однако, используя оригинальный метод main, я получаю следующую трассировку стека:
org.codehaus.jackson.map.JsonMappingException: Argument #0 of constructor [constructor for my.json.stuff.PojoVariant, annotations: {interface org.codehaus.jackson.annotate.JsonCreator=@org.codehaus.jackson.annotate.JsonCreator()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator
Я понимаю, что Джексон хотел бы, чтобы я аннотировал аргументы конструктора именами свойств.Но JSON не содержит ничего для начала.Чего мне не хватает?Или этот подход просто не поддерживается - мне нужно реализовать собственный десериализатор?