2017-09-25 5 views
0

J'ai besoin de désérialiser une chaîne JSON en utilisant Jackson dans des listes de différents types d'objets en fonction de la valeur définie dans l'un des champs. Je veux savoir quelle est la meilleure approche pour créer les différents types de listes et comment je peux mettre en œuvre cela?Jackson Deserialize JSON à la liste de différents types en fonction de la valeur de chaîne

Mon JSON de regarderait le quelque chose comme ceci:

{"test": 
    {"conditions":[....],     
    "consequence": {"actionType":"string", 
        "action": ["value 1","value 2"]}            
    }  
} 

Ainsi, lorsque analysé le serait au-dessus de renvoyer un List<String>

{"test": 
    {"conditions":[....],     
    "consequence": {"actionType":"test", 
        "action": ["test","test"]}            
    }  
} 

et serait au-dessus de retourner un List<Test>

Mon Pojo contient uniquement :

@Data 
public class Consequence { 

    public Consequence(String actionType){ 
     this.actionType = actionType;  
    }; 

    @JsonProperty("ACTIONTYPE") 
    private String actionType; 

    @JsonProperty("ACTION") 
    private List<????> action; 
} 

MISE À JOUR:

Après je mis à jour mon de POJO en utilisant la hiérarchie suivante:

@Data 
public abstract class BaseConsequence { 

    public BaseConsequence(String actionType){ 
     this.actionType = actionType;  
    }; 

    @JsonProperty("ACTIONTYPE") 
    private String actionType; 

} 

@Data 
@DiscriminatorValue(value = "CONCATENATE") 
public class ConcatenateConsequence extends BaseConsequence { 

    public ConcatenateConsequence(String actionType, List<String> concatenateValues) { 
     super(actionType); 
     this.concatenateValues = concatenateValues; 
    } 
    private List<String> concatenateValues; 
} 

@Data 
@DiscriminatorValue(value = "test") 
public class TestConsequence extends BaseConsequence { 

    public TestConsequence(String actionType, List<Test> tests){ 
     super(actionType); 
     this.tests = tests; 
    } 
    private List<Test> tests; 
} 

@Data 
public class Test { 

    public Test(){}; 

    public Test(List<Condition> conditions, BaseConsequence baseConsequence){ 
     this.conditions = conditions; 
     this.baseConsequence = baseConsequence;  
    } 

    @JsonProperty("CONDITIONS") 
    private List<Condition> conditions; 

    @JsonProperty("CONSEQUENCE") 
    private BaseConsequence baseConsequence; 

    @Override 
    public boolean equals(Object o) { 

     if (o == this) return true; 

     if (!(o instanceof Test)) { 
      return false; 
     }   
     Test test = (Test) o; 
     return Objects.equals(conditions, test.conditions) && Objects.equals(baseConsequence, test.baseConsequence); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(conditions, baseConsequence); 
    } 
} 

Je reçois l'erreur suivante:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token 
at [Source: {"TEST":{"CONDITIONS":[{"KEY":"KEY1","VALUES":["FLOAT"],"OPERATOR":""}],"CONSEQUENCE":{"ACTIONTYPE" :{"CONCATENATE": ["VALUE1","VALUE2"]}}}}; line: 1, column: 9] (through reference chain: package.TestCase["TEST"]) 

Répondre

1

Il y a, vous pouvez utiliser deux variantes:

  1. Créer un désérialiseur personnalisé. Voir ici pour des descriptions complètes et des exemples http://www.baeldung.com/jackson-deserialization
  2. La meilleure façon est d'utiliser une classe de base et deux enfants. Chaque enfant devrait porter la mention @DiscriminatorValue. Voir ici pour une description complète et des exemples http://www.baeldung.com/jackson-inheritance
+0

Merci OLEG, je vais vérifier les options et voir si je peux mettre en œuvre un – Orby

+0

Oleg, si je mets en œuvre un désérialiseur personnalisé ai-je besoin de vérifier mon attribut appelé « actionType "dans la méthode de désérialisation écrasée et renvoie le type de liste approprié là-bas? – Orby

+0

Oui. Dans votre désérialiseur vous avez accès à la partie json. Vous devez d'abord lire votre * clé * champ, puis construire un objet avec des données spécifiques, ou créer des objets dirrefernt en dépendent. C'est une fonction très puissante, mais je vous recommande fortement de regarder '@ DiscriminatorValue'. –