propriété Utilisation de l'objet parent pour déterminer la sous-classe lorsque désérialisation?
-
14-10-2019 - |
Question
children: [
{
o kind: "t3"
data: { // ExampleNodeT3 class should be used for kind == t3
+ t3var1: "val1"
+ t3var2: true
}
}
{
o kind: "t4"
data: { // ExampleNodeT4 class should be used for kind == t4
+ t4var1: false
+ t4var2: 2346
}
}
] ... etc.
@JsonTypeInfo(use=Id.NAME, property="kind")
@JsonSubTypes({
@Type(value=ExampleNodeT3.class, name="t3"),
@Type(value=ExampleNodeT4.class, name="t4")})
public abstract class ExampleNode {
...
public void setData(ExampleNode data) {
this.data = data;
}
Lorsque vous essayez de désérialiser cela avec Jackson, les conseils JsonTypeInfo échouent lorsque les données ExampleNode est créé parce que la propriété « genre » est associé à son parent et non visible. J'ai essayé différentes variations de méthodes d'usine et des annotations Jackson, mais parce que Jackson crée l'objet ExampleNode et il passe à setData () lui-même, je ne vois pas de place pour le contrôle quelle classe d'objet est créé.
La solution 2
Cette fonctionnalité n'a pas encore été pris en charge.
Demande d'amélioration de la fonction: http://jira.codehaus.org/browse/JACKSON-275
Plus de détails sur le problème: http://jackson-users.ning.com/forum/topics/how-to-use-a-property-of?commentId=5286555%3AComment%3A2679
Autres conseils
Got ici de Google et a trouvé la solution. en fait ces jours-ci il est possible en raison de l'include = JsonTypeInfo.As.EXTERNAL_PROPERTY, par exemple:
public class Parent {
@JsonProperty("type")
public String type;
@JsonProperty("data")
@JsonInclude(Include.NON_NULL)
public ChildBase ChildBase;
public Parent() {
medias = new HashMap<>();
}
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.EXTERNAL_PROPERTY, property="type")
@JsonTypeIdResolver(ChildBaseByParentTypeResolver.class)
public void setChildBase(ChildBase ChildBase){
this.ChildBase = ChildBase;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChildBase {
public String someStr;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class AggressiveChild extends ChildBase{
public String someStr1;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ChilledChild extends ChildBase{
public String someStr1;
}
public class ChildBaseByParentTypeResolver extends TypeIdResolverBase {
private JavaType superType;
@Override
public void init(JavaType baseType) {
superType = baseType;
}
@Override
public Id getMechanism() {
return Id.NAME;
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
Class<?> subType = ChildBase.class;
switch (id) {
case "agressiveParent":
subType = AggressiveChild.class;
break;
case "chilledParent":
subType = ChilledChild.class;
break;
}
return context.constructSpecializedType(superType, subType);
}
@Override
public JavaType typeFromId(String directiveType) {
throw new NotImplementedException();
}
}
Articles intéressants:
Correct -. L'utilisation des « identificateurs de type externe » (ceux qui ne figurent pas dans l'objet à désérialiser, mais comme frères et soeurs) ne sont pas encore pris en charge
Cela pourrait être mis en œuvre (comme, il n'y a rien soutien fondamental empêchant d'être ajouté) - au-delà de question Jira mentionné qui pourrait aider, une nouvelle demande de fonctionnalité pourrait être déposée pour pouvoir demander directement à utiliser ces identifiants de type. Cela a effectivement été mentionné par plusieurs utilisateurs; peut-être car il existe des formats de données (GeoJSON?) qui utilisent une telle structure de frappe.