2017-07-07 3 views
1

J'ai plusieurs chaînes Json comme suit:Jackson Polymorphism - Classe abstraite sans propriété

{"type1": {"name": "Arnold"}} 
{"type2": {"id": "abcd", "job": "plumber"}} 

La chose que je veux retrouver avec la conversion d'une chaîne JSON à l'une des classes Type1 ou Type2selon la propriété racine de l'élément:

// Type0 abstract class 
public abstract class Type0 { 
} 

// Type1 class.. convert to it if {"type1": {...}} 
@JsonRootName(value = "type1") 
public class Type1 extends Type0 { 
    @JsonProperty("name") 
    String name; 
} 

// Type2 class.. convert to it if {"type2": {...}} 
@JsonRootName(value = "type2") 
public class Type2 extends Type0 { 
    @JsonProperty("id") 
    String id; 

    @JsonProperty("job") 
    String job; 
} 

Comment configurer le ObjectMapper de Jackson pour que je puisse y parvenir désérialisation? Je pense à une logique comme suit, est-ce faisable:

ObjectMapper mapper = new ObjectMapper(); 
result = mapper.readValue(jsonString, Type0.class); 
//TODO: code for deciding whether result is Type1 or Type2 and casting to it 

Répondre

1

Jackson soutient un tel cas WRAPPER_OBJECT. Annoter la classe abstraite comme ceci:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) 
@JsonSubTypes({ 
     @JsonSubTypes.Type(name = "type1", value = Type1.class), 
     @JsonSubTypes.Type(name = "type2", value = Type2.class)}) 
abstract class Type0 {} 

puis lors de l'analyse Type0.class avec readValue vous obtiendrez une instance de la classe dérivée appropriée. Vous n'avez pas besoin de @JsonRootName sur les classes dérivées.