Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

com.google.gson.internal.LinkedHashTreeMap cannot be cast to my object

Tags:

java

json

gson

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".

like image 877
Islam Avatar asked Nov 05 '13 18:11

Islam


People also ask

What is linkedhashtreemap in Gson?

Some background: LinkedHashTreeMap is a class that exists in Gson to defend against hash-collision DoS attacks. It performs like HashMap in the common case and like TreeMap in the worst case. arstechnica.com/business/2011/12/…

How to convert linkedtreemap items to product items?

You can iterate through the ArrayList to convert each LinkedTreeMap item to a Product item. You can use Gson a second time to do the conversion. See example code here: randomgyan.com/… In my opinion, due to type erasure, the parser can't fetch the real type T at runtime. One workaround would be to provide the class type as parameter to the method.

How to keep Gson batchannotateimagesresponse in a class?

The keep statements should go all the way down to just the specific class you need, rather than keeping all of com.google.** and sun.misc.**. The correct rule is something like "-keep class com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse { <fields>; }", depending where the GSON model class you are using is stored.

Why can't I have multiple featuredetails objects in a JSON file?

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.


2 Answers

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(); } 
like image 121
Алексей Avatar answered Oct 12 '22 01:10

Алексей


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)

like image 40
Paul Richter Avatar answered Oct 12 '22 02:10

Paul Richter