1

我需要在 Java 中的 fastxml jackson 中获取 ArrayNode 对象的子数组。

为了更清楚,

  1. 我有一个 fasterxml jackson ArrayNode 对象,它包含例如 100 个对象。
  2. 我有一个限制参数,例如让我们说 5。
  3. 可以用一种非常原始的方式来完成,如下所示,

    ArrayNode arrayNodeRecProducts = (ArrayNode) recProducts;
    int arrayNodeSize = arrayNodeRecProducts.size();
    
    if (limit >= 0 && limit < arrayNodeSize) {
        while (arrayNodeRecProducts.has(limit)) {
            arrayNodeRecProducts.remove(limit);
        }
    }
    

转换为 ArrayNode 类型的“recProducts”对象是一个 fasterxml jackson JsonNode 并包含一个数组。

以上工作但效率很低,因为内部 while 循环运行“arrayNodeSize - 限制”次数以逐个删除 ArrayNode 对象。

是否有我们可以在 ArrayNode 或强制转换的 JsonNode 本身上执行的子数组操作?

谢谢并恭祝安康..

4

2 回答 2

2

感谢“henrik”的回答,你是正确的,因为杰克逊不支持 ArrayNodes 的这种功能。所以我所做的是我下载了 Jackson 数据绑定代码库,并深入了解了为什么他们没有为 ArrayNodes 提供这样的 SubArray 功能(请注意,我指的是数据绑定 2.3.2)。

在内部,Jackson 在 JsonNode 列表中维护 ArrayNode,如下所示,

private final List<JsonNode> _children = new ArrayList<JsonNode>();

令我惊讶的是,出于某种我无法理解的原因,他们没有提供可以通过使用此包含列表的 subList 方法轻松完成的 SubArray 操作。例如如下,

public List<JsonNode> subArray(int fromIndex, int toIndex) {
    return _children.subList(fromIndex, toIndex);
}

上面的方法可以让我摆脱我面临的麻烦,但它根本不包含在库中。

所以我在我的代码库中所做的就是在运行时使用反射简单地侵入这个私有列表,并在运行时调用 subList 操作,如下所示。

ArrayNode arrayNodeRecProducts = (ArrayNode) recProducts;
if (limit >= 0 && limit < arrayNodeRecProducts.size()) {
    Field innerArrayNode = ArrayNode.class.getDeclaredField("_children");
    innerArrayNode.setAccessible(true);
    List<JsonNode> innerArrayNodeChildNodes = (List<JsonNode>) innerArrayNode.get(arrayNodeRecProducts);
    List<JsonNode> limitedChildNodes = innerArrayNodeChildNodes.subList(0, limit);
    innerArrayNode.set(arrayNodeRecProducts, limitedChildNodes);
}

我知道上面的代码不会在所有情况下都有效,但对于我的情况来说它工作正常。

同时,我知道这违反了我们严密的 OO 原则封装,但我可以忍受,原因在下面的帖子中解释。

反射 API 不会破坏数据封装的目的吗?

于 2015-02-26T08:44:50.650 回答
0

杰克逊没有这样的支持。

我将创建一个新的 ArrayNode 并将其填充到极限,这在大多数情况下会更有效:

ArrayNode limited = objectMapper.createArrayNode();
for(JsonNode e : src) {
        limited.add(e);
        if (limited.size() == limit) {
            break;
        }
    }
于 2015-02-24T14:43:34.330 回答