我正试图找到一种方法来使用jackson的多态反序列化功能,它将基于嵌套在标头/控件对象中的属性反序列化我的对象:
JSON 1-类别1:
{
"id":"someId",
"header":{
"category":"CATEGORY1",
"somOtherProperty":"someValue"
}
"nextField":"nextValue",
...
}
JSON 2-类别2
{
"id":"someId",
"header":{
"category":"CATEGORY2",
"somOtherProperty":"someValue"
}
"nextField":"nextValue",
...
}
父类(类似这样的注释)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "category")
@JsonSubTypes({
@Type(value = Category1Class.class, name = "CATEGORY1"),
@Type(value = Category2Class.class, name = "CATEGORY2") })
public class ParentClass{
private Header header;
private String nextField;
...
}
public class Header{
private String category;
private String somOtherProperty;
...
}
子类
@JsonTypeName("CATEGORY1")
public class Category1Class extends ParentClass{
...
}
@JsonTypeName("CATEGORY2")
public class Category2Class extends ParentClass{
...
}
jackson中是否有现成的功能可以让我进行这种反序列化,或者我遗漏了什么?
如果查看Jackson Api,则属性类型反序列化器(PropertyTypeDeserializer)是负责使用属性识别子类型的类。如果查看该类,有一个名为反序列化TypedFromObject的方法,该方法将使用JsonTypeIdResolver识别子类。我们可以扩展这个类并重写方法反序列化类型(deserializeTypedFromObject)和属性(property)。
package com.dilipkumarg.tutorials.dynamicsubtype;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer;
import com.fasterxml.jackson.databind.node.TreeTraversingParser;
import com.fasterxml.jackson.databind.type.SimpleType;
public class CustomTypeDeserializer extends AsPropertyTypeDeserializer {
public CustomTypeDeserializer(
final JavaType bt, final TypeIdResolver idRes,
final String typePropertyName, final boolean typeIdVisible, final Class<?> defaultImpl) {
super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl);
}
public CustomTypeDeserializer(
final AsPropertyTypeDeserializer src, final BeanProperty property) {
super(src, property);
}
@Override
public TypeDeserializer forProperty(
final BeanProperty prop) {
return (prop == _property) ? this : new CustomTypeDeserializer(this, prop);
}
@Override
public Object deserializeTypedFromObject(
final JsonParser jp, final DeserializationContext ctxt) throws IOException {
JsonNode node = jp.readValueAsTree();
Class<?> subType = findSubType(node);
JavaType type = SimpleType.construct(subType);
JsonParser jsonParser = new TreeTraversingParser(node, jp.getCodec());
if (jsonParser.getCurrentToken() == null) {
jsonParser.nextToken();
}
/* 16-Dec-2010, tatu: Since nominal type we get here has no (generic) type parameters,
* we actually now need to explicitly narrow from base type (which may have parameterization)
* using raw type.
*
* One complication, though; can not change 'type class' (simple type to container); otherwise
* we may try to narrow a SimpleType (Object.class) into MapType (Map.class), losing actual
* type in process (getting SimpleType of Map.class which will not work as expected)
*/
if (_baseType != null && _baseType.getClass() == type.getClass()) {
type = _baseType.narrowBy(type.getRawClass());
}
JsonDeserializer<Object> deser = ctxt.findContextualValueDeserializer(type, _property);
return deser.deserialize(jsonParser, ctxt);
}
protected Class<?> findSubType(JsonNode node) {
Class<? extends ParentClass> subType = null;
String cat = node.get("header").get("category").asText();
if (cat.equals("CATEGORY1")) {
subType = Category1Class.class;
} else if (cat.equals("CATEGORY2")) {
subType = Category2Class.class;
}
return subType;
}
}
在扩展类中,我们使用idResolver绕过了子类型标识,而是使用头
字段的类别
字段动态标识。
我们需要TypeResolverBuilder
来创建新的CustomTypeDeserializer
实例。
package com.dilipkumarg.tutorials.dynamicsubtype;
import java.util.Collection;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
public class CustomTypeResolver extends StdTypeResolverBuilder {
@Override
public TypeDeserializer buildTypeDeserializer(final DeserializationConfig config, final JavaType baseType, final Collection<NamedType> subtypes) {
return new CustomTypeDeserializer(baseType, null,
_typeProperty, _typeIdVisible, _defaultImpl);
}
}
现在我们有了一个用于子类型识别的CustomTypeResolver
,但是当Jackon找到“家长类”时,它将如何知道查看这个类?
我们可以通过两种方式来做到这一点:
>
使用JsonTypeResolver注释。这是推荐的方法,因为我们不需要配置任何东西。
在包含类型解析器之后,我们的新父类将是:
package com.dilipkumarg.tutorials.dynamicsubtype;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonTypeResolver;
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonTypeResolver(CustomTypeResolver.class)
public class ParentClass {
private Header header;
private String nextField;
...
}
请参见此处
如何使用多态反序列化和嵌套类型信息属性反序列化它?我在中使用嵌套属性,如下所示: 鉴于config Jackson抱怨无法找到属性:
我正在尝试使用Jakson反序列化一个嵌套的多态类型。也就是说,我的顶级类型引用了另一个多态类型,该类型最终由不抽象的类扩展。这不起作用,它会抛出一个异常。 下面是我尝试做的一个简化的例子。 我得到了关于抽象类型的标准异常。 让我解释一下我的用例。我有一个描述数据工作流的Json文档。我在“Level One”有一个抽象类型,描述对单个值的操作。我派生了一堆不是抽象的类,它们实现了公共操作(我用@
这适用于顶级对象,但不适用于嵌套对象。例如,如果嵌套对象是特殊对象,则仍将其反序列化为公共对象。 我想做的是告诉Jackson:“无论嵌套级别如何,如果ObjType=Special,使用SpecialObject,否则使用GeneralObject”。我研究了多态反序列化,并尝试使用@JSONSubtypes,但无法正确设置该逻辑。如何确保特殊对象被反序列化到适当的类中,即使它们是嵌套的?
问题内容: 我正在使用Jackson的反序列化包含接口作为其属性之一的对象的JSON表示。可以在此处看到代码的简化版本: https://gist.github.com/sscovil/8735923 基本上,我有一个具有两个属性的类:和。JSON模型如下所示: 该属性被定义为所谓的接口,我有实现它的几个类(例如,)。这个想法是图像文件与文档文件等具有不同的属性(高度,宽度)。 我在工作过的例子这
我使用的是spring-boot-starter-parent 1.3.3和jackson-core-asl:jar:1.9.2。我无法创建与person关联的对象(组),因为组是用person名称创建的。回复如下… person.java group.java 如果我将@jsonProperty()放在group.java中,那么一切工作都很好。 此外,如果我使用@restResource(ex
我看过jackson反序列化@JsonTypeInfo的一个例子,那就是: 我试过了,效果很好。现在的问题是,在示例类中,Cat和Dog是从Animal中引用的,我想避免这种情况。有没有一种方法可以将类型绑定从类动物中移除,并且仍然进行反序列化工作?谢谢