gpt4 book ai didi

java - Jackson ObjectMapper 在转换为 POJO 时忽略某些键

转载 作者:行者123 更新时间:2023-12-01 16:40:44 25 4
gpt4 key购买 nike

这是我的课

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) 有效,但这会忽略所有不需要的键。如果我只想忽略某些不需要的键,并且给定的键不属于我的对象构造函数或不需要的集合,那么它会抛出异常,该怎么办?

最佳答案

我建议的方法:

在类上保留 @JsonIgnoreProperties(ignoreUnknown = true) 注释。

假设输入以下 JSON:

{
"argA": 5,
"unneededkey": 6,
"unexpectedKey": 99
}

创建一个包含允许的字段名称的集合(其中“allowed”是 MyObject 类中存在的字段,或者可以安全地忽略它):

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 选择如何继续。要么抛出异常(使用意外字段名称列表来获取信息),要么以通常的方式创建对象:

MyObject object = mapper.readValue(json, MyObject.class);

这样做的缺点是它可能会遍历 JSON 两次 - 一次检查是否有问题,另一次(假设没有问题)反序列化数据。

注意事项:

(1) 上面的代码假设一个平面 JSON 结构 - 没有嵌入对象 - 与您的问题中的内容相匹配。为了获得更大的灵 active ,您可以使用以下 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;
}

致谢:参见 this answer了解详情。

(2) 我考虑过自定义反序列化器:

public class MyDeserializer extends StdDeserializer<Util.MyObject> { 
...
}

但是您仍然会遇到同样的问题 - 更不用说调用正确的构造函数所需的额外工作,具体取决于它找到的非空字段值的特定组合。

关于java - Jackson ObjectMapper 在转换为 POJO 时忽略某些键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61867532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com