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 特性/注释配置
谁能解释一下:
- 如何以及何时在 Spring 中配置 ObjectMapper(何时
注解配置(JsonCreator、JsonProperty)、Feature
application.yml 中的配置(如接受大写),自定义
在 ObjectMapper
上注册的 JsonComponents 等
- 这个 objectMapper 实例的生命周期是多少?
- ContextConfiguration 的生命周期是多少,
反序列化配置?
- Spring 和 Jackson 背景如何相互关联?
我查找相关主题,其他答案相关位置:
- Spring 和 Jackson 上下文不一样(但是为什么,这是什么意思?)
- 你需要一个 HandlerInstantiator 来自动装配(我认为这在我的 spring 版本中已经是默认的,这也不能解释为什么我的自定义反序列化器在自动装配 ObjectMapper 时没有任何错误消息反序列化器)
一般来说,您可以使用 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 托管之外创建新的对象映射器之外,我没有找到任何解决方案。
环境:
我使用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 配置不正确(意味着 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 特性/注释配置谁能解释一下:
- 如何以及何时在 Spring 中配置 ObjectMapper(何时 注解配置(JsonCreator、JsonProperty)、Feature application.yml 中的配置(如接受大写),自定义 在 ObjectMapper 上注册的 JsonComponents 等
- 这个 objectMapper 实例的生命周期是多少?
- ContextConfiguration 的生命周期是多少, 反序列化配置?
- Spring 和 Jackson 背景如何相互关联?
我查找相关主题,其他答案相关位置:
- Spring 和 Jackson 上下文不一样(但是为什么,这是什么意思?)
- 你需要一个 HandlerInstantiator 来自动装配(我认为这在我的 spring 版本中已经是默认的,这也不能解释为什么我的自定义反序列化器在自动装配 ObjectMapper 时没有任何错误消息反序列化器)
一般来说,您可以使用 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 托管之外创建新的对象映射器之外,我没有找到任何解决方案。