tags:

views:

69

answers:

1

I can't work out how to deserialize an array inside a JSON object using Gson. The json object that i'm trying to deserialize looks like this:

{"item0":3,
 "item1":1,
 "item2":3,
 "array":[
    {"arrayItem1":321779321,
     "arrayItem2":"asdfafd",
     "arrayItem3":"asasdfadf"}]}

I manage to build a class that looks like this:

public class Watchlist {
 private int itemn0;
 private int itemn1;
 private int itemn2;
 private Object array;

}

But when gson tries to deserialize the array it throws an exception:

com.google.gson.JsonParseException: Type information is unavailable, and the target object is not a primitive: <my gson array>

Can someone please tell me how to deserialize this?

A: 

There's a couple of problems here:

One, I don't think you're using the array like you think you are. You have "arrayItem1" through 3, but they are contained in a single JSON object within the array... so the array actually only has one item.

The array should probably be something like:

"array": [
  321779321,
  "asdfafd",
  "asasdfadf"
]

The second is that the type of array in your Java class is Object... that doesn't give Gson any type information to use for translating the object. Normally, you'd want to declare the type of the object the array maps to as List<String> or List<Integer> or some such. This gives it the necessary type information... a JSON array can map to a List, and the String type parameter tells it what type to translate the array's contents to.

The problem with the array in your example is that it isn't homogenous... it has a number and two strings in it. Generally, mixing types like this in an array/collection should be avoided. You can, however, declare the type of your array object as List<String>... you'll just get the String form of the number.

ColinD
Ah yea. Thanks for pointing that out. You are right. This array only has 1 item. A better example would have been:{"item0":3, "item1":1, "item2":3, "array":[ {"arrayItem1":321779321, "arrayItem2":"asdfafd", "arrayItem3":"asasdfadf"}, {"arrayItem1":234, "arrayItem2":"asdfafd", "arrayItem3":"asdfa"}]}
limmy
ColinD, Thanks for the explanation. Based on what you said I managed to get the above code working by having converting my array in to a List<HashMap<String,String>>. but I was wondering if I could convert that into a List<MyObject>? Is that not possible at all based on your explanation?Thanks.
limmy
Yes, if you defined a class that has fields that correspond to the fields of the JSON objects in your array (`MyObject`) and declare the array field as `List<MyObject>`, that will work fine!
ColinD
Thanks. I'm going to give it another try. The API i'm calling just threw me another JSON curve ball. One of the values of the object in the array is another array! I think i may have picked the worse API to learn JSON on. sigh.
limmy
Is there documentation for the API you're calling that tells you exactly what to expect from each object? You just need to make a Java type that matches up with the format of each JSON object you may receive and then nest them as expected from the API.
ColinD
Unfortunately not. But i'll just have to work through the problems I guess.
limmy
Using the List<MyObject> type in the deserialization I'm getting an exceptioncom.google.gson.JsonParseException: The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@1cfb549 failed to deserialized json object [{"ListingId":111111111,"Title":"first title"},{"ListingId":2222222222,"Title":"second title"},{"ListingId":33333333,"Title":"third title"}] given the type com.google.gson.ParameterizedTypeImpl@5c1343I've defined by the parent object as
limmy
My objects now look like My code for my object is nowpublic class Watchlist { private int itemn0; private int itemn1; private int itemn2; private List<MyObject> array;}And MyObject looks likepublic class MyObject{ private int ListingId; private String Title;}It looks right to me so I don't understand why I'm getting an exception. It works if I revert back to List<HashMap<String,String>>.
limmy
It would help if you'd edit your question to include that information. It isn't really readable in a comment.
ColinD
Sorry about that. I've decided to give this a rest for now and just use xpath. not as convenient but at least I can get it work. Thanks for your help.
limmy