gpt4 book ai didi

java - Jackson ObjectMapper在Spring中的生命周期

转载 作者:行者123 更新时间:2023-12-04 03:52:38 31 4
gpt4 key购买 nike

环境:

我使用 spring boot 版本 2.3.3.RELEASE


问题

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

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

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

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


示例

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

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

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

在反序列化器中获取 ObjectMapper

但是这个 ObjectMapper 配置不正确(意味着例如类/方法上的注释被忽略)。

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

@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 typeFoo:Argument #0 has no property name, is not Injectable: can not use asCreator [constructor forFoo,annotations: {interfacecom.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}]

是否可以在我的自定义反序列化器中使用与 Autowiring 时其他组件中使用的相同的 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 始终是一个新实例。现在我使用 Autowiring 的 objectMapper。但这有什么影响呢?


结论:

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

关于配置,我的意思是:在类、方法、字段/注册模块和 JsonComponents 上启用 Jackson 特性/注释配置

谁能解释一下:

  • 如何以及何时在 Spring 中配置 ObjectMapper(何时注解配置(JsonCreator、JsonProperty)、Featureapplication.yml 中的配置(如接受大写),自定义在 ObjectMapper 上注册的 JsonComponents 等
  • 这个 objectMapper 实例的生命周期是多少?
  • 什么是 ContextConfiguration 的生命周期,反序列化配置?
  • Spring 和 Jackson 上下文如何相互关联?

我查找了相关主题,其他相关答案在哪里:

  • Spring 和 Jackson 的上下文不同(但为什么,这是什么意思?)
  • 你需要一个 HandlerInstantiator 来 Autowiring (我假设这在我的 spring 版本中已经是默认的,这也不能解释为什么在其中一个反序列化器中 Autowiring ObjectMapper 时没有任何错误消息就没有选择我的自定义反序列化器)

最佳答案

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

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

检查这个 answer - 它会回答你的其他问题

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

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

关于java - Jackson ObjectMapper在Spring中的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64260678/

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