【发布时间】:2021-01-23 09:24:26
【问题描述】:
环境:
我用的是spring boot 2.3.3.RELEASE版本
问题
我使用@JsonComponent 注解注册了自定义反序列化器。
在一些模块和测试中我@Autowirejacksons ObjectMapper。
问题 1:我不能在 @JsonComponent 中使用 @Autowire ObjectMapper,否则 @JsonComponent 将被完全忽略(没有错误消息)
问题 2:我想在 @JsonComponent 中拥有相同的 ObjectMapper 实例(或至少具有相同配置的 OM),我可以通过 Autowire 在其他组件中获得该实例
示例
由于我不想对某些字段进行自定义反序列化,因此我使用 ObjectMapper 在我的自定义反序列化程序中使用 convertValue()。
我注意到,我不能 @Autowire 我的任何反序列化器中的 ObjectMapper,否则不会为我的应用程序中自动装配的其他 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 忽略了此注释。这会导致以下错误消息:
类型的类型定义无效
Foo: 参数 #0 没有属性名称,不可注入:不能用作 Creator [构造函数 福, 注释:{界面 com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}]
是否可以在我的自定义解串器中拥有与 Autowired 时在其他组件中使用的相同的 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 时我的自定义反序列化器没有被拾取而没有任何错误消息)
【问题讨论】:
-
我读了你的问题大约 3 次,但仍然不知道你在问什么或试图实现什么。看起来您想向 Jackson 注册一些东西,这也将使用 jackson aka 循环依赖项。
-
好的,我会尽量让这一点更清楚。我稍后会编辑它。尽管底部的问题应该很清楚,与上面的问题无关。
-
@ManuelWaltschek 更清晰,更专注。您似乎想在一篇文章中提出多个问题。
-
您是否尝试过创建一个返回已配置
ObjectMapper实例的bean? -
@LHCHIN 是的,正如 svr 在答案中所说,这仍然会导致未解决的循环依赖/引用。
标签: java json spring spring-boot jackson