Java 在Jackson自定义反序列化程序中读取跳过的子级

Java 在Jackson自定义反序列化程序中读取跳过的子级,java,json,jackson,deserialization,jackson-modules,Java,Json,Jackson,Deserialization,Jackson Modules,我有一个特定类的反序列化程序,在读取字段时需要一些排序。 假设我班上有两个字段(field1和field2),为了阅读field2,它首先需要field1 例如,对于以下json数据,它可以工作,因为当反序列化程序解析field2时,field1已设置: {"field1": 3, "field2": 4} 但是,如果我们反转字段: {"field2": 4, "field1": 3} 我需要通过jp跳过field2。skipChildren,因为未设置field1。解析field1时,Ja

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

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

{"field1": 3, "field2": 4}
但是,如果我们反转字段:

{"field2": 4, "field1": 3}
我需要通过
jp跳过
field2
。skipChildren
,因为未设置
field1
。解析
field1
时,Jackson应重新读取并解析
field2

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


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

自定义反序列化程序需要使用流式API。无法返回、重新分析等

您是否为需要这种特殊处理的字段类型或包含字段的类注册了自定义反序列化程序

如果为包含这些字段的类注册反序列化程序,则只需使用流式API,读入实例的所有字段,临时存储它们(例如,在HashMap中),然后分配值即可


顺便说一句:你的问题闻起来像问题。也许你应该发布另一个关于原因的问题,你需要在这里解决这个问题,看看是否有更好的方法解决它。

最后我找到了一种方法。这实际上是一个解决办法,但它通过了我编写的测试。 当您将字节数组传递给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()


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

您有一个问题,即您依赖对象成员顺序,而RFC for JSON(RFC 7159)说这与此无关。你为什么要订单?为什么不尝试反序列化这两个字段?@fge,因为某个特定字段包含有关如何解析其他字段的信息。将JSON树解析为通用JsonNode始终是一个选项,但它会带来开销,因此我想避免它。@fge,因为您了解Avro,所以我想做的是将JSON解析为Avro模型。JSON中的一些字段包含关于Avro模式的信息,因此为了解析树,首先我需要知道这些值。您可以从这里查看代码:我找到了一种使用自定义JsonParser的方法。不幸的是,HashMap带来了开销,正如我所说的,性能对于应用程序的这一部分至关重要。