web-dev-qa-db-fra.com

com.google.gson.internal.LinkedHashTreeMap ne peut pas être converti vers mon objet

J'ai un fichier JSON qui ressemble à 

{
    "SUBS_UID" : {
        "featureSetName" : "SIEMENSGSMTELEPHONY MULTISIM",
        "featureName" : "MULTISIMIMSI",
        "featureKey" : [{
                "key" : "SCKEY",
                "valueType" : 0,
                "value" : "0"
            }
        ]
    },
}

Donc, la clé est une chaîne "SUBS_ID" et la valeur est un modèle appelé FeatureDetails qui contient les attributs "featureSetName, featureName, ..." . J'ai donc lu le fichier JSON en utilisant google.json lib comme ceci,

HashMap<String, FeatureDetails> featuresFromJson = new Gson().fromJson(JSONFeatureSet, HashMap.class);

alors j'essaie de faire une boucle sur cette HashMap en obtenant la valeur et la jette dans mon modèle FeatureDetails,

for (Map.Entry entry : featuresFromJson.entrySet()) {
                    featureDetails = (FeatureDetails) entry.getValue();
                }

et voici mon modèle FeatureDetails,

public class FeatureDetails {

    private String featureSetName;
    private String featureName;
    private ArrayList<FeatureKey> featureKey;
    private String groupKey;
    private String groupValue;

    public FeatureDetails() {
        featureKey =  new ArrayList<FeatureKey>();
    }

    public ArrayList<FeatureKey> getFeatureKey() {
        return featureKey;
    }

    public void setFeatureKey(ArrayList<FeatureKey> featureKey) {
        this.featureKey = featureKey;
    }

    public String getGroupKey() {
        return groupKey;
    }

    public void setGroupKey(String groupKey) {
        this.groupKey = groupKey;
    }

    public String getGroupValue() {
        return groupValue;
    }

    public void setGroupValue(String groupValue) {
        this.groupValue = groupValue;
    }

    public String getFeatureName() {
        return featureName;
    }

    public void setFeatureName(String featureName) {
        this.featureName = featureName;
    }

    public String getFeatureSetName() {
        return featureSetName;
    }

    public void setFeatureSetName(String featureSetName) {
        this.featureSetName = featureSetName;
    }
} 

mais j'ai une exception "com.google.gson.internal.LinkedHashTreeMap ne peut pas être converti en com.asset.vsv.models.FeatureDetail".

19
Islam

essaye ça:

HashMap<String, FeatureDetails> featuresFromJson = new Gson().fromJson(JSONFeatureSet, new TypeToken<Map<String, FeatureDetails>>() {}.getType());

et quand vous parcourez votre carte de hachage, faites ceci:

for (Map.Entry<String, FeatureDetails> entry : featuresFromJson.entrySet()) {
                    FeatureDetails featureDetails = entry.getValue();
}
31
Алексей

Si vous voyez cela, c'est parce que vous demandez à GSON de désérialiser la structure JSON à l'aide de la structure HashMap dans la ligne.

... = new Gson().fromJson(JSONFeatureSet, HashMap.class);
                                          ^^
                                          Right here

Par conséquent, GSON ne sait pas que les sous-objets du JSON sont autre chose que de simples paires clé-valeur, même si la structure peut correspondre à la structure de votre objet FeatureDetails.

Une solution consiste à créer un modèle qui englobe votre objet FeatureDetails, qui agira comme la racine de toute la structure. Cet objet pourrait ressembler à quelque chose comme ça:

public class FeatureDetailsRoot{
    private FeatureDetails SUBS_UID; // poor naming, but must match the key in your JSON
}

Et enfin, vous passeriez la classe de ce modèle:

= new Gson().fromJson(JSONFeatureSet, FeatureDetailsRoot.class)

Mettre à jour

En réponse à votre question dans le commentaire concernant la possibilité d'ajouter/d'avoir plusieurs objets FeatureDetails, le problème est que votre JSON ne reflète pas ce type de structure. Cela signifie que la clé "SUBS_UID" pointe vers un seul objet et non vers un tableau. Si vous souhaitez avoir cette capacité, alors votre JSON devra être modifié pour qu'il affiche un tableau d'objets, comme ceci:

{
    "SUBS_UID" : [{
       "featureSetName" : "Feature set name #1",
       ...attributes for feature #1
     },
     {
       "featureSetName" : "Feature set name #2",
       ...attributes for feature #2
     },
     ...other features
     ]
}

Et ensuite, vous pouvez simplement modifier la classe racine afin qu’elle contienne une liste d’objets FeatureDetails, comme suit:

public class FeatureDetailsRoot{
    private List<FeatureDetails> SUBS_UID;
}

Faites-moi savoir si cela a un sens (ou si je vous ai mal compris)

5
Paul Richter

le code est en Kotlin: utilisez val type = object : TypeToken<HashMap<String, FoodLogEntry>>() {}.type Gson().fromJson(dataStr, type) 

au lieu de val type = object : TypeToken<Map<String, FoodLogEntry>>() {}.type Gson().fromJson(dataStr, type) note: HashMap au lieu de Map

0
Abhilash Das