gpt4 book ai didi

json - Jackson JSON 多态性

转载 作者:行者123 更新时间:2023-12-01 03:58:02 25 4
gpt4 key购买 nike

我一直在尝试应用 http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html 上的内容)\,并将其应用于我一直在做的事情。虽然它非常适合我将在 JSON 结构中称为“外部”元素的内容,但我遇到了一个令人沮丧的问题,即没有太多文档。

首先,我的代码有点像下面这样:

interface Parameters {
// Couple random properties -- no problem here

SubTypeParameters getSubTypeParameters(); // where SubTypeParameters are polymorphic
void setSubTypeParameters(SubTypeParameters value);
}

@JsonSubTypes({
@JsonSubTypes.Type(name = "a", value = ASubTypeParameters.class),
@JsonSubTypes.Type(name = "b", value = BSubTypeParameters.class)
})
interface SubTypeParameters {
String getValue();
void setValue(String value);
}

@JsonTypeName(value = "a")
class ASubTypeParameters implements SubTypeParameters {
// getter/setter implemented
}

@JsonTypeName(value = "b")
class BSubTypeParameters implements SubTypeParameters {
// getter/setter implemented
}

我想要做的是在链接的博客文章中实现第 6 个选项,以便 JSON 将如下所示(注意没有指定“类型”元素——它基于上下文):
{
// other properties corresponding to the Parameters object
"a": {
"value": "value for a"
}
}

或者
{
// other properties corresponding to the Parameters object
"b": {
"value": "value for b"
}
}

我试图避免的是在 JSON 对象中引入另一个“类型”变量。相反,我更愿意使用提供到上述 JSON 示例中的上下文来知道我应该基于“a”或“b”的存在构建 ASubTypeParameters 或 BSubTypeParameters 对象。

有趣的是,Parameters 类/对象也是多态的,所以我注册了自己的自定义反序列化器类,如下所示:
ObjectMapper mapper = new ObjectMapper();
StdDeserializer<Parameters> parameterDeserializer = new ParameterDeserializer();
SimpleModule module = new SimpleModule ( ... ); // simplifying this--no problem here
module.addDeserializer(Parameters.class, parameterDeserializer);
mapper.registerModule(module);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

但是,当上述反序列化器尝试反序列化上述 JSON 示例中的任何一个时,它将到达尝试反序列化“a”或“b”的部分,并表明它不知道如何处理这些属性(UnrecognizedPropretyException如果我删除未知属性行上的失败)。我的问题实际上归结为:我错过了什么(注释或其他)?

我也试过添加:
mapper.registerSubtypes(ASubTypeParameters.class, BSubTypeParameters.class)


mapper.registerSubtypes(
new NamedType(ASubTypeParameters.class, "a"),
new NamedType(BSubTypeParameters.class, "b")
);

无济于事。

我知道我已经很接近了,我的猜测是我需要编写某种自定义子类型处理程序,但是文档似乎缺少我想做的事情(尤其是当您反序列化多态类型时)/class 还包含一个多态元素)。

最佳答案

使用 Jackson,您可以配置为使用以下注释将类型信息存储为单个字段的名称:@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT) .结果应该类似于您的 JSON 示例。

我稍微修改了你的代码来演示它:

public class JacksonPolymorphic2 {
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@JsonSubTypes.Type(name = "a", value = ASubTypeParameters.class),
@JsonSubTypes.Type(name = "b", value = BSubTypeParameters.class)
})
interface SubTypeParameters {
String getValue();
void setValue(String value);
}

@JsonTypeName(value = "a")
static class ASubTypeParameters implements SubTypeParameters {
ASubTypeParameters(String value) {
this.value = value;
}

private String value;
@Override
public String getValue() {
return value;
}

@Override
public void setValue(String value) {
this.value = value;
}
}

@JsonTypeName(value = "b")
static class BSubTypeParameters implements SubTypeParameters {
BSubTypeParameters(String value) {
this.value = value;
}

private String value;
@Override
public String getValue() {
return value;
}

@Override
public void setValue(String value) {
this.value = value;
}
}

public static void main(String[] args) throws JsonProcessingException {
ASubTypeParameters a = new ASubTypeParameters("aType");
BSubTypeParameters b = new BSubTypeParameters("bType");
List<? super SubTypeParameters> list = new ArrayList<>();
list.add(a);
list.add(b);

ObjectMapper mapper = new ObjectMapper();
System.out.printf(mapper
.writerWithType(new TypeReference<List<SubTypeParameters>>() {})
.withDefaultPrettyPrinter()
.writeValueAsString(list));
}
}

输出:
[ {
"a" : {
"value" : "aType"
}
}, {
"b" : {
"value" : "bType"
}
} ]

关于json - Jackson JSON 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15624950/

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