【问题标题】:How to modify a collection deserialiser so that it produces a collection filtered out by given conditions?如何修改集合反序列化器,使其生成按给定条件过滤掉的集合?
【发布时间】: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&lt;Link&gt; 并按链接有效性过滤该列表。当我们介绍LinkDeserialiser时,我们找到了一种反序列化Links的正确方法,即

nodeParser.readValueAs(new TypeReference<List<Link>>() {});

但问题是,我们现在不知道将过滤器link -&gt; link.valid() 放在哪里。 nodeParser 将使用有效和无效的Links 填充列表。

我宁愿不写JsonDeserializer&lt;Collection&lt;Link&gt;&gt;,这似乎是一个枯燥的想法。

问题

我很想得到以下任何问题的答案:

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


【解决方案1】:

简短而简单:解析所有条目并删除无效的条目。

nodeParser.readValueAs(new TypeReference<List<Link>>() {})
    .removeIf((Link link) -> !link.valid());

【讨论】:

  • 谢谢。但是,Link#valid 是基本规则,无论上下文和调用者如何,都应遵循。我不想(也不能)强制调用者通过我的(私有)规则过滤掉获得的集合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 2020-09-23
  • 1970-01-01
  • 2020-10-31
  • 2016-12-20
  • 1970-01-01
相关资源
最近更新 更多