所以我目前正在使用Jackson将JSON反序列化为java对象。一切都运作良好,但我也有一些领域,如:
对于这种JSON文件:
{
"uid": 7,
"asset": 123,
"currency1_balance": 0,
"currency2_balance": 0,
... ...
"currencyN_balance": 0,
}
我们可以通过下面的java类反序列化它:
@Test
public void testBalanceJSON() throws IOException {
// Read in the JSON from the example resources
InputStream is = BalanceTest.class.getResourceAsStream("/example-balance-data.json");
//Use Jackson to parse it
ObjectMapper mapper = new ObjectMapper();
Balance balance = mapper.readValue(is, Balance.class);
}
... ...
@JsonIgnoreProperties(ignoreUnknown = true)
public class Balance {
private final BigDecimal uid;
private final BigDecimal asset;
private final BigDecimal currency1Balance;
private final BigDecimal currency2Balance;
// ... ...
private final BigDecimal currencyNBalance;
@JsonCreator
public Balance(@JsonProperty("uid") BigDecimal uid, @JsonProperty("asset") BigDecimal asset,
@JsonProperty("currency1_balance") BigDecimal currency1Balance,
@JsonProperty("currency2_balance") BigDecimal currency2Balance,
// ... ...
@JsonProperty("currencyN_balance") BigDecimal currencyNBalance) {
this.uid = uid;
this.asset = asset;
this.currency1Balance = currency1Balance;
this.currency2Balance = currency2Balance;
// ... ...
this.currencyNBalance = currencyNBalance;
}
}
在上面的例子中,我必须编写大量代码来处理" currencyN_balance"之间的映射。和" currencyNalance"。一旦添加/删除货币,我就必须相应地修改代码,这是非常不灵活的。 然后我找到了以下方法来自定义反序列化过程。
@JsonCreator
public static Balance Create(Map<String, Object> jsonMap) {
//Resovle the map
BigDecimal uid = new BigDecimal(jsonMap.get("uid").toString());
BigDecimal asset = new BigDecimal(jsonMap.get("asset").toString());
for (Map.Entry<String, Object> entry : jsonMap.entrySet()){
if (entry.getKey().startsWith("currency")) {
//Do something...
}
}
//Then construct the Balance instance and return
}
通过使用上面的方法,我可以摆脱枯燥和容易出错的映射。但是我不能利用注释来处理一些参数&#39;反序列化(例如,uid,资产)。
有没有什么方法可以结合上述两种技术的优势? (使用带有参数的注释,例如uid,资产,同时能够自定义货币映射)
感谢。
答案 0 :(得分:1)
这是JSON的憎恶。那货币_ [1..n] _balance应该在一个数组中...因为它是一个数组,但是编码得很糟糕。
无论如何,这不是你的错(我希望)。为此你可以使用Jackson @JsonAnyGetter和@JsonAnySetter注释(如果你想序列化和反序列化这个类,否则你只能使用其中一个)。
例如
@JsonAnySetter
public void set(String name, String value) {
//do funky transformation/assigment
}
杰克逊会用任何无法映射的属性调用该方法。因此,您可能需要添加一些逻辑来忽略您不感兴趣的属性。