gpt4 book ai didi

java - 在 Jackson Custom Deserializer 中读取跳过的 child

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:10:58 26 4
gpt4 key购买 nike

我有一个特定类的反序列化器,它在读取字段时需要一些排序。假设我的类中有两个字段(field1field2),为了读取 field2,它首先需要 field1.

例如,对于以下 json 数据,它可以工作,因为当反序列化器解析 field2 时,field1 已经设置:

{"field1": 3, "field2": 4}

但是如果我们反转字段:

{"field2": 4, "field1": 3}

我需要通过 jp.skipChildren 跳过 field2 因为 field1 没有设置。当field1被解析后,Jackson应该重新读取并解析field2

一个选项是解析 field2 而不是跳过并将其保存在一个变量中,这样当设置 field1 时,它可以使用保存 field2 中数据的变量。然而;根据 field1 的值,我可能不需要解析 field2,因此我正在寻找更好的解决方案,因为这部分代码的性能至关重要。

我正在使用 Mapper.readValue(byte[], MyClass.class) 方法,Jackson 似乎使用 ReaderBasedJsonParser 进行解析。尽管可以获取 token 位置,但我找不到设置 token 位置的方法。

最佳答案

终于找到方法了。这实际上是一种解决方法,但它通过了我编写的测试。当您将字节数组传递给 mapper.readValue 时,它​​使用 ReaderBasedJsonParser 遍历数组并解析 JSON 树。

public static class SaveableReaderBasedJsonParser extends ReaderBasedJsonParser {
private int savedInputPtr = -1;

public SaveableReaderBasedJsonParser(IOContext ctxt, int features, Reader r, ObjectCodec codec, CharsToNameCanonicalizer st, char[] inputBuffer, int start, int end, boolean bufferRecyclable) {
super(ctxt, features, r, codec, st, inputBuffer, start, end, bufferRecyclable);
}

public void save() {
savedInputPtr = _inputPtr;
}

public boolean isSaved() {
return savedInputPtr>-1;
}

public void load() {
_currToken = JsonToken.START_OBJECT;
_inputPtr = savedInputPtr;
_parsingContext = _parsingContext.createChildObjectContext(0, 0);
}
}

当您使用此 JsonParser 时,将传递给反序列化器 EventDeserializer.deserialize(JsonParser, DeserializationContext) 的 JsonParser 实例将是一个 SaveableReaderBasedJsonParser 这样你就可以安全地转换它了。

当你想保存位置时,调用jp.save() 这样当你需要返回时,你可以直接调用jp.load() .

正如我所说,这实际上是一种变通方法,但是当您需要这种功能并且不想出于性能原因对树进行两次解析时,您可以尝试一下。

关于java - 在 Jackson Custom Deserializer 中读取跳过的 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28467776/

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