![](/img/trans.png)
[英]How to ignore pojo annotations while using Jackson ObjectMapper?
[英]Jackson ObjectMapper ignore certain keys when converting to POJO
這是我的 class
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.*;
public class Util {
public static void main(String[] args) throws JsonProcessingException {
String json = "{ \"argA\" : 5, \"unneededkey\" : 6}";
ObjectMapper mapper = new ObjectMapper();
MyObject object3 = mapper.readValue(json, MyObject.class);
System.out.println(object3);
}
@ToString
@RequiredArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class MyObject {
public MyObject(int argA) {
this.argA = argA;
}
public MyObject(int argA, boolean argB) {
this.argA = argA;
this.argB = argB;
}
public MyObject(int argA, int argC, int argD) {
this.argA = argA;
this.argC = argC;
this.argD = argD;
}
public MyObject(int argA, String argE) {
this.argA = argA;
this.argE = argE;
}
public int argA = 1;
public boolean argB;
public int argC = 4;
public int argD = 5;
public String argE;
}
}
@JsonIgnoreProperties(ignoreUnknown = true) 有效,但這會忽略所有不需要的鍵。 如果我只想忽略某些不需要的鍵,並且如果我得到的鍵不屬於我的 object 構造函數或在不需要的集合中,它會拋出異常。
我建議的方法:
在 class 上保留@JsonIgnoreProperties(ignoreUnknown = true)
注釋。
假設以下輸入 JSON:
{
"argA": 5,
"unneededkey": 6,
"unexpectedKey": 99
}
創建一個包含允許字段名稱的集合(其中“允許”是MyObject
class 中存在的字段,或者可以安全地忽略它):
Set<String> allowedFields = new HashSet(Arrays.asList(
"argA", "argB", "argC", "argD", "argE",
"unneededkey", "unneededkey2"));
然后對 JSON 進行如下處理:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(json);
Iterator<String> fieldNames = rootNode.fieldNames();
boolean fieldFailure = false;
Set<String> unexpectedFields = new HashSet();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
if (!allowedFields.contains(fieldName)) {
fieldFailure = true;
unexpectedFields.add(fieldName);
}
}
然后,您可以根據 boolean fieldFailure
選擇如何繼續。 要么拋出異常(使用意外字段名稱列表獲取信息),要么以通常的方式創建 object:
MyObject object = mapper.readValue(json, MyObject.class);
不利的一面是它可能會遍歷 JSON 兩次 - 一次檢查問題,再次(假設沒有問題)反序列化數據。
注意事項:
(1) 上面的代碼假設一個扁平的 JSON 結構 - 沒有嵌入對象 - 這與您在問題中的內容相匹配。 為了更靈活,您可以使用以下findKeys
方法遞歸訪問所有節點:
Map<String, Object> treeMap = mapper.readValue(json, Map.class);
List<String> keys = Lists.newArrayList();
List<String> result = findKeys(treeMap, keys);
private List<String> findKeys(Map<String, Object> treeMap, List<String> keys) {
treeMap.forEach((key, value) -> {
if (value instanceof LinkedHashMap) {
Map<String, Object> map = (LinkedHashMap) value;
findKeys(map, keys);
}
keys.add(key);
});
return keys;
}
致謝:有關詳細信息,請參閱此答案。
(2) 我考慮了一個自定義反序列化器:
public class MyDeserializer extends StdDeserializer<Util.MyObject> {
...
}
但是您仍然會遇到同樣的問題 - 更不用說調用正確的構造函數所需的額外工作,具體取決於它找到的非空字段值的特定組合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.