【发布时间】:2023-04-03 04:23:02
【问题描述】:
问题
我需要仅使用原始属性对@Autowired Spring bean(我使用的是 Spring Boot 2.0.4)进行多态 JSON(反)序列化。
由于 bean 是“增强的”,它是我的“原始”bean 的子类,类名以 $$EnhancerBySpringCGLIB$$12345 之类的结尾。
目前尝试过
为了避免 Jackson 尝试序列化“增强”部分,我已将我的 bean 声明为自身的超类型
@JsonSerialize(as=MyClass.class)
它按预期工作。
但是,当我尝试使用
进行多态序列化时@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.WRAPPER_OBJECT)
放在该类实现的接口上,包装对象的关键是增强类的名字! JSON 字符串的其余部分都可以,即只包含“原始”类的属性。不用说,我现在不能反序列化它,因为上面提到的子类已经不存在了。
使用JsonTypeInfo.Id.NAME 破坏了多态反序列化的整个想法,恕我直言。如果没有其他方法,我可以通过查询ApplicationContext 找出目标类。
编辑:
这是一个 Foo Bar 示例:
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.WRAPPER_OBJECT)
public class Foo {
private String foo = "Foo";
@JsonSerialize(as = Bar.class)
public static class Bar extends Foo {
private String bar = "Bar";
}
public static class UnwantedMutant extends Bar {
private String aThing = "Not welcome";
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
UnwantedMutant mutant = new UnwantedMutant();
System.out.println(mapper.writeValueAsString(mutant));
}
}
打印出来
{"mypackage.Foo$UnwantedMutant":{"foo":"Foo","bar":"Bar"}}
同时
{"mypackage.Foo$Bar":{"foo":"Foo","bar":"Bar"}}
是预期的/期望的。
那么,问题来了:
“纯”杰克逊的意思有没有解决这个问题的方法,或者我只能忍受它?
【问题讨论】:
-
@MithatKonuk :您提到的链接都描述了 JsonTypeInfo.Id.NAME 场景,这是不可接受的,请参阅问题。想象一下序列化一个接口的 30 个不同实现的实例 - 在接口声明中注册它们中的每一个?
-
@badbishop 我没有意识到!
标签: java spring-boot polymorphism json-deserialization jackson2