gpt4 book ai didi

java - 使用 Jackson 对 JSON 文件进行多态反序列化

转载 作者:行者123 更新时间:2023-12-02 13:35:32 25 4
gpt4 key购买 nike

根据 JSON 文件的内容,我想将其反序列化为父类(super class)或子类。

如果它看起来像这样,则应该反序列化为父类(super class):

{
"id":"123",
"title":"my title",
"body":"my body"
}

或者子类,如果它看起来像这样:

{
"id":"123",
"title":"my title",
"body":"my body",
"tags":["tag1", "tag2"]
}

所以唯一的区别是 tags 数组,它应该被反序列化为字符串数组。但如果我通过 POST 请求触发 Jersey (Dropwizard) 中的反序列化,它会返回 {"code":400,"message":"Unable to process JSON"}

这是父类(super class):

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({ @JsonSubTypes.Type(name = "subdocument", value = SubDocument.class) })
public class SuperDocument {

private String id;
private String title;
private String body;

public SuperDocument() {

}

@JsonCreator
public SuperDocument(@JsonProperty("id") String id, @JsonProperty("title") String title, @JsonProperty("body") String body) {
this.id = id;
this.title = title;
this.body = body;
}

@JsonProperty("id")
public String getId() {
return id;
}

@JsonProperty("id")
public void setId(String id) {
this.id = id;
}

... the other getters and setters ...
}

这是子类:

@JsonTypeName("subdocument")
public class SubDocument extends SuperDocument {

private String[] tags;

public SubDocument() {

}

@JsonCreator
public SubDocument(@JsonProperty("id") String id, @JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") String[] tags) {
super(id, title, body);
this.tags = tags;
}

@JsonProperty("tags")
public String[] getTags() {
return tags;
}

@JsonProperty("tags")
public void setTags(String[] tags) {
this.tags = tags;
}
}

你知道我做错了什么吗?

最佳答案

JsonTypeInfo 需要一个可以标识您的子类/父类(super class)的属性。例如:

{
"id":"123",
"title":"my title",
"body":"my body",
"type":"superdocument"
}

{
"id":"123",
"title":"my title",
"body":"my body",
"tags":["tag1", "tag2"],
"type":"subdocument"
}

然后修改SuperDocument注释,如下所示。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,property="type")
@JsonSubTypes({ @JsonSubTypes.Type(name = "subdocument", value = SubDocument.class),@JsonSubTypes.Type(name = "superdocument", value = SuperDocument.class) })

public class SuperDocument {

}

如果您不想引入额外的属性“type”,那么您可能必须编写自定义类型解析器和类型反序列化器,如下所示。

    public class DocumentTypeResolver extends StdTypeResolverBuilder {
@Override
public TypeDeserializer buildTypeDeserializer(
final DeserializationConfig config, final JavaType baseType, final Collection<NamedType> subtypes) {
return new DocumentDeserializer(baseType, null,
_typeProperty, _typeIdVisible, _defaultImpl);
}
}

自定义类型反序列化器

    public static class DocumentDeserializer extends AsPropertyTypeDeserializer {

public DocumentDeserializer(final JavaType bt, final TypeIdResolver idRes, final String typePropertyName, final boolean typeIdVisible, final Class<?> defaultImpl) {
super(bt, idRes, typePropertyName, typeIdVisible, defaultImpl);
}

public DocumentDeserializer(final AsPropertyTypeDeserializer src, final BeanProperty property) {
super(src, property);
}

@Override
public TypeDeserializer forProperty(final BeanProperty prop) {
return (prop == _property) ? this : new DocumentDeserializer(this, prop);
}

@Override
public Object deserializeTypedFromObject(final JsonParser jp, final DeserializationContext ctxt) throws IOException {
JsonNode node = jp.readValueAsTree();
Class<?> subType =null;
JsonNode tags = node.get("tags");
if (tags == null) {
subType=SuperDocument.class;
} else {
subType=SubDocument.class;
}
JavaType type = SimpleType.construct(subType);
JsonParser jsonParser = new TreeTraversingParser(node, jp.getCodec());
if (jsonParser.getCurrentToken() == null) {
jsonParser.nextToken();
}

JsonDeserializer<Object> deser = ctxt.findContextualValueDeserializer(type, _property);
return deser.deserialize(jsonParser, ctxt);

}

}

现在注释您的 SuperDocument 类,如下所示

@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonTypeResolver(DocumentTypeResolver.class)
public class SuperDocument {

}

关于java - 使用 Jackson 对 JSON 文件进行多态反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43020466/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com