Spring 中 Jackson ObjectMapper 的生命周期

Lifecycle of Jackson ObjectMapper in Spring

环境:

我使用spring引导版本2.3。3.RELEASE


问题

我用 @JsonComponent 注释注册自定义反序列化器。

在一些模块和测试中我 @Autowire jacksons ObjectMapper.

问题 1:我无法在 @JsonComponent 中使用 @Autowire ObjectMapper,否则 @JsonComponent 将被完全忽略(没有错误消息)

问题 2:我想在 @JsonComponent(或至少具有相同配置的 OM)中拥有相同的 ObjectMapper 实例,我可以在其他组件中通过 Autowire 获得该实例


示例

因为我不想对某些字段进行自定义反序列化,所以我使用 ObjectMapper 在我的自定义反序列化器中使用 convertValue()

我注意到,我无法在我的任何反序列化器中 @Autowire ObjectMapper,否则在我的应用程序中自动装配的其他 ObjectMapper 将不会获取配置(因此反序列化器未正确注册)

我正在使用 (ObjectMapper) jsonParser.getCodec();

在反序列化器中获取 ObjectMapper

但是此 ObjectMapper 配置不正确(意味着 class/methods 上的注释被忽略)。

我想反序列化我的对象如下:

@Test
void testDeserializeFoo() throws IOException {
    ObjectMapper om = new ObjectMapper(); // this is obtained by jsonParser in deserializer but it behaves the same, since the ObjectMapper lacks the configuration
    InputStream is = getClass().getResourceAsStream("/json/foo.json");
    JsonNode fooNode = om.readTree(is);
    Foo foo =  om.convertValue(fooNode, Foo.class);
    log.info("Foo: " + foo);
}

Foo 的构造函数用 @JsonCreator 注释。

问题是,这个注释被我从自定义反序列化器中的解析器获得的 ObjectMapper 忽略了。这会导致以下错误消息:

Invalid type definition for type Foo: Argument #0 has no property name, is not Injectable: can not use as Creator [constructor for Foo, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}]

是否可以在我的自定义反序列化器中使用自动装配时在其他组件中使用的相同 ObjectMapper 实例?


编辑

可能的解决方案/测试:

我正在这样测试我的解串器:

private JsonParser getJsonParser(String resource) throws IOException {
        InputStream src = getInputStream(resource);
        return objectMapper.createParser(src);
}
    
@Test
void testDeserializeFoo() throws IOException {
    JsonParser parser = getJsonParser("/json/foo.json");
    Foo foo = deserializer.deserialize(parser, null);
    System.out.println(foo);
}

问题是 getParser() 方法中的 objectMapper 始终是一个新实例。现在我使用自动装配的 objectMapper。但这有什么作用呢?


结论:

我想在我的 JsonComponents(自定义反序列化器)中使用与 Autowired ObjectMapper(由 spring 在其他组件中提供)相同的 ObjectMapper 实例,或者至少使用具有相同配置的 ObjectMapper。

我的意思是配置:在 类、方法、字段/注册模块和 JsonComponents

上启用 Jackson 特性/注释配置

谁能解释一下:

我查找相关主题,其他答案相关位置:

一般来说,您可以使用 Jackson2ObjectMapperBuilder 和 build() 来生成应用了所有最新设置的新对象映射器实例。默认的 ObjectMapper 由 JackonAutoConfiguration 中的 JackonsObjectMapperConfiguration 提供。所有 jackson2 对象映射器构建器实例均由 JacksonAutoConfiguration 中的 JacksonObjectMapperBuilderConfiguration 创建。有关配置对象映射器的详细信息,请参见 here

如果您不喜欢 JacksonAutoConfiguration 中的标准默认设置,您可以使用 Jackson2ObjectMapperBuilderCustomizerConfiguration 进一步自定义 jackson2 对象映射器构建器

查看此 - 它会回答您的其他问题

即将发布 - 使用 jackson2objectbuilder/build 或为使用 JsonComponent 注释注释的 ser/deser 自动装配对象映射器时遇到同样的问题。所有这些注释都由 JacksonAutoConfiguration 中定义的 JsonComponentModule bean 扫描,并注册到默认对象映射器和由 jackson2 对象映射器构建器创建的所有实例。所以不可能使用未构建的对象映射器并同时注册 ser/deser。你是对的,异常( beancurrentlyincreationexception )被 spring 抑制并且 json 组件模块没有注册到对象映射器的消息未解析循环引用。

除了在 spring 托管之外创建新的对象映射器之外,我没有找到任何解决方案。