我有以下类,必须将其序列化为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 {
}
}
这样derivedOne
容器将只保留Derived1.class实例,而derivedTwo
-仅保留Derived2.class实例。
Jackson中是否有一种方法不使用额外的type
属性,而是通过包含的容器名称来确定目标类?
我试图使其与自定义TypeIdResolver
一起使用,但没有成功。
答案 0 :(得分:2)
取决于您的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文章可能对您有所帮助。