![](/img/trans.png)
[英]How to deserialize Spring's ResponseEntity with Jackson ObjectMapper (probably with using @JsonCreator and Jackson mixins)
[英]Deserialize JSON with Jackson and @JsonCreator
我從正在開發的第三方工具接收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]],
}}
問題出在variants標記上,尤其是“行”。 看起來好像用@JsonValue批注對“行”進行了序列化,以消除否則將成為每個“行”一部分的字段名。 而是將一個附加的“列”字段序列化為至少提及一次列名。
沒有variants標簽,我已經成功地使用ObjectMapper將JSON反序列化為POJO:
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不包含任何開頭。 我想念什么? 還是根本不支持這種方法-我必須實現自定義解串器嗎?
從jackson注釋javadoc中 , @JsonPropertyOrder
用於序列化,而不是反序列化:
可用於定義序列化對象屬性時使用的排序(可能是部分)的注釋。
另外,在使用@JsonCreator
注釋構造函數時,構造函數必須為:
- 對於參數,不帶JsonProperty批注的單參數構造函數 / factory方法:如果是這樣,這就是所謂的“委托創建者”,在這種情況下, Jackson首先將JSON綁定到參數的類型中,然后調用creator 。
- 構造函數/工廠方法,其中每個參數都用JsonProperty或JacksonInject注釋,以指示要綁定的屬性的名稱。
問題是您嘗試從json列表["17", 19561093, ".", ..]
反序列PojoVariant
。 傑克遜很聰明,但沒有那么聰明。 在這里他需要一些幫助,您可以幫助他實現自定義解串器。 我們不想這樣做,所以我們希望可以找到其他東西。
提示來自@JsonCreator
javadoc(第一個項目符號,粗體文本)。 並且,由於Jackson知道如何將列表綁定到對象數組中,因此我們可以像下面這樣重寫PojoVariant
構造函數:
@JsonCreator
public PojoVariant(Object[] params) {
this.chr = (String) params[0];
this.pos = (int) params[1];
this.id = (String) params[2];
this.ref = (String) params[3];
this.alt = (String) params[4];
this.quality = (int) params[5];
this.filter = (String) params[6];
this.type = (String) params[7];
this.genotype = (String) params[8];
this.alignPos = (int) params[9];
this.basePos = (int) params[10];
this.signalPos = (int) params[11];
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.