Mar*_*cin 30 java json jackson deserialization
我想将JSON字符串转换为java对象,但此对象的类包含杰克逊无法实例化的抽象字段,并且不生成该对象.告诉它关于抽象类的一些默认实现的最简单方法是什么,比如
setDefault(AbstractAnimal.class, Cat.class);
Run Code Online (Sandbox Code Playgroud)
或者根据JSON属性名称来决定实现类,例如.对于JSON对象:
{
...
cat: {...}
...
}
Run Code Online (Sandbox Code Playgroud)
我愿意:
setImpl("cat", Cat.class);
Run Code Online (Sandbox Code Playgroud)
我知道Jackson可以在JSON中嵌入类信息,但我不想让我使用的JSON格式复杂化.我想通过设置默认实现类或属性名称('cat')来决定使用哪个类 - 就像在XStream库中一样,您可以在其中编写:
xStream.alias("cat", Cat.class);
Run Code Online (Sandbox Code Playgroud)
有没有办法这样做,特别是在一行中,还是需要更多的代码?
Sta*_*Man 41
有多种方式; 在1.8版本之前,最简单的方法可能是:
@JsonDeserialize(as=Cat.class)
public abstract class AbstractAnimal { ... }
Run Code Online (Sandbox Code Playgroud)
至于基于属性的决定,最好使用@JsonTypeInfo
,它自动嵌入(写入时)和使用类型信息.
有多种类型的信息(类名,逻辑类型名称),以及包含机制(as-included-property,as-wrapper-array,as-wrapper-object).这个页面:https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization解释了一些概念.
可以在这里找到带有非常清晰示例的完整答案:/sf/answers/2127068611/
杰克逊将此称为多态反序列化。
它绝对帮助我解决了我的问题。我有一个抽象类,我将其保存在数据库中,需要将其解组为类的具体实例(可以理解)。
它将向您展示如何正确注释父抽象类,以及如何教 Jackson 如何在解组时在运行时从可用的子类候选者中进行选择。
小智 5
如果您不想用额外的字段污染您的 JSON,也不想用注释污染您的类,您可以编写一个非常简单的模块和反序列化器,使用您想要的默认子类。由于一些样板代码,它不止一行,但仍然相对简单。
class AnimalDeserializer extends StdDeserializer<Animal> {
public AnimalDeserializer() {
super(Animal.class);
}
public Animal deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException {
return jsonParser.readValueAs(Cat.class);
}
}
class AnimalModule extends SimpleModule {
{
addDeserializer(Animal.class, new AnimalDeserializer());
}
}
Run Code Online (Sandbox Code Playgroud)
然后为 ObjectMapper 注册这个模块就可以了(Zoo 是具有 Animal 字段的容器类)。
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new AnimalModule());
return objectMapper.readValue(json, Zoo.class);
Run Code Online (Sandbox Code Playgroud)