gpt4 book ai didi

java - 有没有办法通过在 Jackson 中包含数组来确定抽象对象的目标类型?

转载 作者:行者123 更新时间:2023-11-30 02:03:07 25 4
gpt4 key购买 nike

我有以下类,必须将其序列化为 JSON 并返回到类实例:

public class Container {

private List<Base> derivedOne;
private List<Base> derivedTwo;

@JsonCreator
public Container(@JsonProperty("derivedOne") List<Base> derivedOne,
@JsonProperty("derivedTwo") List<Base> derivedTwo) {
this.derivedOne = derivedOne;
this.derivedTwo = derivedTwo;
}

public static class Derived1 extends Base {

private String derivedField1;

public Derived1(String derivedField1) {
this.derivedField1 = derivedField1;
}
}

public static class Derived2 extends Base {

private String derivedField2;

public Derived2(String derivedField2) {
this.derivedField2 = derivedField2;
}
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include =
JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Derived1.class, name = "one"),
@JsonSubTypes.Type(value = Derived2.class, name = "two")
})
public abstract static class Base {
}

}

这样 categories 容器将仅保存 Derived1.class 实例,而 衍生Two - 仅保存 Derived2.class 实例。

Jackson 有没有办法不使用额外的 type 属性,通过包含的容器名称来确定目标类?

我试图让它与自定义 TypeIdResolver 一起工作,但没有成功。

最佳答案

取决于您的 json 值。

您可以使用type来指示反序列化的类型。

下面是完整的代码。

public class Container {

private List<Base> derivedOne;
private List<Base> derivedTwo;

@JsonCreator
public Container(@JsonProperty("derivedOne") List<Base> derivedOne,
@JsonProperty("derivedTwo") List<Base> derivedTwo) {
this.derivedOne = derivedOne;
this.derivedTwo = derivedTwo;
}

public static class Derived1 extends Base {

private String derivedField1;

public String getDerivedField1() {
return derivedField1;
}

public void setDerivedField1(String derivedField1) {
this.derivedField1 = derivedField1;
}
}

public static class Derived2 extends Base {

private String derivedField2;

public String getDerivedField2() {
return derivedField2;
}

public void setDerivedField2(String derivedField2) {
this.derivedField2 = derivedField2;
}
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include =
JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Derived1.class, name = "one"),
@JsonSubTypes.Type(value = Derived2.class, name = "two")
})
public abstract static class Base {
}

public static void main(String[] args) throws IOException {

String jsonStr = "{\"derivedOne\":[{\"type\":\"one\",\"derivedField1\":\"derivedField1\"},{\"type\":\"two\",\"derivedField2\":\"derivedField2\"}],\"derivedTwo\":[{\"type\":\"one\",\"derivedField1\":\"derivedField1\"},{\"type\":\"two\",\"derivedField2\":\"derivedField2\"}]}";

ObjectMapper objectMapper = new ObjectMapper();
Container container = objectMapper.readValue(jsonStr, Container.class);
}
}

使用@JsonTypeIdResolver

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include =
JsonTypeInfo.As.PROPERTY, property = "type")
@JsonTypeIdResolver(ContainerResolver.class)
public abstract static class Base {
}

public static void main(String[] args) throws IOException {

String jsonStr = "{\"derivedOne\":[{\"type\":\"one\",\"derivedField1\":\"derivedField1\"},{\"type\":\"two\",\"derivedField2\":\"derivedField2\"}],\"derivedTwo\":[{\"type\":\"one\",\"derivedField1\":\"derivedField1\"},{\"type\":\"two\",\"derivedField2\":\"derivedField2\"}]}";

ObjectMapper objectMapper = new ObjectMapper();
Container container = objectMapper.readValue(jsonStr, Container.class);
}


public class ContainerResolver extends TypeIdResolverBase {

private JavaType superType;

@Override
public void init(JavaType baseType) {
this.superType = baseType;
}

@Override
public String idFromValue(Object value) {
return idFromValueAndType(value, value.getClass());
}

@Override
public String idFromValueAndType(Object value, Class<?> suggestedType) {

String typeId = null;
switch (suggestedType.getSimpleName()) {
case "Derived1":
typeId = "one";
break;
case "Derived2":
typeId = "two";
}
return typeId;
}

@Override
public JavaType typeFromId(DatabindContext context, String id) throws IOException {

Class<?> subType = null;
switch (id) {
case "one":
subType = Container.Derived1.class;
break;
case "two":
subType = Container.Derived2.class;
}
return context.constructSpecializedType(superType, subType);
}

@Override
public JsonTypeInfo.Id getMechanism() {
return JsonTypeInfo.Id.NAME;
}
}

This文章可能对您有帮助。

关于java - 有没有办法通过在 Jackson 中包含数组来确定抽象对象的目标类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52168185/

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