【发布时间】:2019-08-30 10:58:26
【问题描述】:
域
有一个班级Link
public final class Link implements Serializable {
private final String _title;
private final String _href;
private final List<Link> _links;
}
还有一个类 LinkDeserialiser 可以从 JSON 中反序列化 Link 对象
public final class LinkDeserialiser extends JsonDeserializer<Link> {
@Override
public Link deserialize(JsonParser parser, DeserializationContext context) throws IOException {
final JsonNode node = context.readValue(parser, JsonNode.class);
return Link.builder()
.title(node.path(Constants.TITLE).asText().trim())
.href(node.path(Constants.HREF).asText().trim())
.links(loadLinks(node.path(Constants.LINKS)))
.build();
}
}
问题
在LinkDeserialiser之前,我们有一个方法
public static List<Link> readLinks(JsonNode node) {
List<Link> links = new ArrayList<>();
node.forEach(childNode -> {
Link link = new Link(childNode);
if (link.valid()) {
links.add(link);
}
});
return links;
}
将JsonNode 解析为List<Link> 并按链接有效性过滤该列表。当我们介绍LinkDeserialiser时,我们找到了一种反序列化Links的正确方法,即
nodeParser.readValueAs(new TypeReference<List<Link>>() {});
但问题是,我们现在不知道将过滤器link -> link.valid() 放在哪里。 nodeParser 将使用有效和无效的Links 填充列表。
我宁愿不写JsonDeserializer<Collection<Link>>,这似乎是一个枯燥的想法。
问题
我很想得到以下任何问题的答案:
1) 如何修改一个集合反序列化器,使其产生一个被给定条件过滤掉的集合?
2) 有没有办法让集合反序列化器“容错”,所以当抛出异常时,它会继续将对象收集到集合中? (一个例外是一种过滤器)
更新 1
Link#valid 是一项基本规则,无论上下文和调用者如何,都应遵守。我不想(也不能)强制调用者通过我的(私有)规则过滤获得的集合。
更新 2
来自CollectionDeserializer的来源
Object value;
if (t == JsonToken.VALUE_NULL) {
if (_skipNullValues) {
continue;
}
value = _nullProvider.getNullValue(ctxt);
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
result.add(value);
无论任何条件,似乎都添加了反序列化的value。我正在考虑扩展该类并自行过滤生成的集合。
【问题讨论】:
-
对不起,nodeParser 是什么?
-
@dai 是由
codec.treeAsTokens(node)获得的JsonParser,用于解析大型 JSON 模式中的特定节点
标签: java json jackson jackson-databind