Reputation: 1727
I have JSON file looks like
{
"SUBS_UID" : {
"featureSetName" : "SIEMENSGSMTELEPHONY MULTISIM",
"featureName" : "MULTISIMIMSI",
"featureKey" : [{
"key" : "SCKEY",
"valueType" : 0,
"value" : "0"
}
]
},
}
So the key is a String "SUBS_ID" and the value is a model called FeatureDetails which contains attributes "featureSetName,featureName,...". So i read from the JSON file using google.json lib like this,
HashMap<String, FeatureDetails> featuresFromJson = new Gson().fromJson(JSONFeatureSet, HashMap.class);
then I'm trying to loop over this HashMap getting the value and cast it to my FeatureDetails model,
for (Map.Entry entry : featuresFromJson.entrySet()) {
featureDetails = (FeatureDetails) entry.getValue();
}
and here is my FeatureDetails Model,
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;
}
}
but i got an exception "com.google.gson.internal.LinkedHashTreeMap cannot be cast to com.asset.vsv.models.FeatureDetail".
Upvotes: 26
Views: 55159
Reputation: 1438
the code is in Kotlin:
use val type = object : TypeToken<HashMap<String, FoodLogEntry>>() {}.type
Gson().fromJson(dataStr, type)
instead of val type = object : TypeToken<Map<String, FoodLogEntry>>() {}.type
Gson().fromJson(dataStr, type)
note: HashMap instead of Map
Upvotes: 0
Reputation: 1847
try this:
HashMap<String, FeatureDetails> featuresFromJson = new Gson().fromJson(JSONFeatureSet, new TypeToken<Map<String, FeatureDetails>>() {}.getType());
and when you going through your hash map do this:
for (Map.Entry<String, FeatureDetails> entry : featuresFromJson.entrySet()) {
FeatureDetails featureDetails = entry.getValue();
}
Upvotes: 34
Reputation: 11072
The reason you're seeing this is because you're telling GSON to deserialize the JSON structure using the structure of a HashMap
in the line
... = new Gson().fromJson(JSONFeatureSet, HashMap.class);
^^
Right here
As a result, GSON has no idea that the sub objects in the JSON are anything other than simple key-value pairs, even though the structure may match the structure of your FeatureDetails
object.
One solution is to create a model which wraps your FeatureDetails
object, which will act as the root of the entire structure. This object might look something like this:
public class FeatureDetailsRoot{
private FeatureDetails SUBS_UID; // poor naming, but must match the key in your JSON
}
And finally, you'd pass that model's class:
= new Gson().fromJson(JSONFeatureSet, FeatureDetailsRoot.class)
Update
In answer to your question in the comment regarding the ability to add / have multiple FeatureDetails
objects, the problem presently is that your JSON does not reflect that kind of structure. Meaning, the "SUBS_UID"
key points to a single object, not an array objects. If you would like to have this ability, then your json will need to be altered so that it shows an array of objects, like this:
{
"SUBS_UID" : [{
"featureSetName" : "Feature set name #1",
...attributes for feature #1
},
{
"featureSetName" : "Feature set name #2",
...attributes for feature #2
},
...other features
]
}
And then you can simply alter the root class so that it contains a list of FeatureDetails
objects, like so:
public class FeatureDetailsRoot{
private List<FeatureDetails> SUBS_UID;
}
Let me know if that makes sense (or whether I've misunderstood you)
Upvotes: 6