【发布时间】:2019-03-28 11:12:42
【问题描述】:
我有一个用于查询一些数据的外部服务。数据将采用以下两种格式之一(第一种是“遗留”,但需要支持):
{
"foo": "John Smith"
}
或
{
"foo": {
"name": "John Smith",
"bar": "baz"
}
}
我想映射到以下 POJO:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Outer {
private Foo foo;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Foo {
String name;
String bar;
}
}
第二种格式的数据(foo 是一个对象)应该像任何其他 POJO 一样反序列化,但是给定第一种格式的数据(foo 是字符串),将其转换为Foo 的实例, 我想打电话给new Foo(<foo>, null)。为此,我创建了一个自定义反序列化器(@JsonComponent 意味着这个反序列化器将在 spring 之前通过 Jackson Module 接口注册到一个有点全局的ObjectMapper):
@JsonComponent
public class FooDeserializer extends JsonDeserializer<Outer.Foo> {
@Override
public Outer.Foo deserialize(JsonParser parser, DeserializationContext context)
throws IOException {
JsonNode node = parser.getCodec().readTree(parser);
if (node.isTextual()) {
return new Foo(node.asText(), null);
}
return <delegate to next applicable deserializer>;
}
}
我无法弄清楚如何执行“委托给下一个适用的反序列化器”部分,因为我尝试过的每个解决方案(例如 parser.getCodec().treeToValue(node, Outer.Foo.class))最终都会再次使用相同的自定义反序列化器,从而导致无限递归。这甚至可能吗?
【问题讨论】:
标签: java json spring-boot jackson json-deserialization