0
 data: [
        { 
         type: "earnings" 
         info: { 
                earnings: 45.6 
                dividends: 4052.94 
                gains: 0 
                expenses: 3935.24 
                shares_bought: 0 
                shares_bought_user_count: 0 
                shares_sold: 0 
                shares_sold_user_count: 0 
               } 
         created: "2011-07-04 11:46:17" 
        }
        { 
         type: "mentions" 
         info: [ 
                { 
                 type_id: "twitter" 
                 mentioner_ticker: "LOANS" 
                 mentioner_full_name: "ERICK STROBEL" 
                } 
               ] 
         created: "2011-06-10 23:03:02" 
        }
       ]

Here's my problem : like you can see the "info" is different in each of one, one is a json object, and one is a json array, i usually choose Gson to take the data, but with Gson we can't do this kind of thing . How can i make it work ?

Tsunaze
  • 3,204
  • 7
  • 44
  • 81

5 Answers5

1

If you want to use Gson, then to handle the issue where the same JSON element value is sometimes an array and sometimes an object, custom deserialization processing is necessary. I posted an example of this in the Parsing JSON with GSON, object sometimes contains list sometimes contains object post.

If the "info" element object has different elements based on type, and so you want polymorphic deserialization behavior to deserialize to the correct type of object, with Gson you'll also need to implement custom deserialization processing. How to do that has been covered in other StackOverflow.com posts. I posted a link to four different such questions and answers (some with code examples) in the Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied thread. In this thread, the particular structure of the JSON objects to deserialize varies from the examples I just linked, because the element to indicate the type is external of the object to be deserialized, but if you can understand the other examples, then handling the problem here should be easy.

Community
  • 1
  • 1
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
0

Both key and value have to be within quotes, and you need to separate definitions with commas:

{ 
  "key0": "value0", 
  "key1": "value1", 
  "key2": [ "value2_0", "value2_1" ] 
}

That should do the trick!

Leonard
  • 3,012
  • 2
  • 31
  • 52
0

The info object should be of the same type with every type. So check the type first. Pseudocode:

if (data.get('type').equals("mentions") {
    json_arr = data.get('info');
}
else if (data.get('type').equals("earnings") {
    json_obj = data.get('info');
}

I'm not sure that helps, cause I'm not sure I understand the question.

c00kiemon5ter
  • 16,994
  • 7
  • 46
  • 48
0

If changing libraries is an option you could have a look at Jackson, its Simple Data Binding mode should allow you to deserialize an object like you describe about. A part of the doc that is probably quite important is this, your example would already need JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES to work...

Clarification for Bruce: true, in Jackson's Full Data Binding mode, but not in Simple Data Binding mode. This is simple data binding:

public static void main(String[] args) throws IOException {
    File src = new File("test.json");
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(JsonParser.Feature. ALLOW_UNQUOTED_FIELD_NAMES, true);
    mapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);

    Object root = mapper.readValue(src, Object.class);
    Map<?,?> rootAsMap = mapper.readValue(src, Map.class);
    System.out.println(rootAsMap);
}

which with OP's sightly corrected sample JSON data gives:

{data=[{type=earnings, info={earnings=45.6, dividends=4052.94, gains=0,
expenses=3935.24, shares_bought=0, shares_bought_user_count=0, shares_sold=0,
shares_sold_user_count=0}, created=2011-07-04 11:46:17}, {type=mentions,
info=[{type_id=twitter, mentioner_ticker=LOANS, mentioner_full_name=ERICK STROBEL}],
created=2011-06-10 23:03:02}]}

OK, some hand-coding needed to wire up this Map to the original data, but quite often less is more and such mapping code, being dead simple has the advantage of being very easy to read/maintain later on.

fvu
  • 32,488
  • 6
  • 61
  • 79
  • The problem described concerns the info element value is sometimes an object and sometimes an array, and the object in the array has different elements than its counterpart (that was not in an array). The next release of Jackson will have a feature to automagically unwrap single element arrays, which might be applicable to this particular situation, but the issue of the varying object structure/elements still needs to be addressed. For this, Jackson's polymorphic deserialization features may apply. – Programmer Bruce Jul 04 '11 at 22:10
  • @Bruce last time I played with it polymorphic deserialization in Jackson was still pretty scary - maybe I should try it again. In the mean time I also added an code sample that uses simple databinding to deserialize OP's sample data... – fvu Jul 04 '11 at 22:53
  • Object root = mapper.readValue(src, Object.class); -- That is one of the great things about Jackson. It'll deserialize just about anything to a Java data structure composed of only Java SE types. In just one line of code. I haven't yet seen another Java-to/from-JSON library that can do that. – Programmer Bruce Jul 04 '11 at 23:19
  • "last time I played with it polymorphic deserialization in Jackson was still pretty scary" I find it to be easy, now. I posted a few examples at http://goo.gl/nVKBZ – Programmer Bruce Jul 04 '11 at 23:20
0

Use simply org.json classes that are available in android: http://developer.android.com/reference/org/json/package-summary.html

You will get a dynamic structure that you will be able to traverse, without the limitations of strong typing.....

This is not a "usual" way of doing things in Java (where strong typing is default) but IMHO in many situations even in Java it is ok to do some dynamic processing. Flexibility is better but price to pay is lack of compile-time type verification... Which in many cases is ok.

Jarek Potiuk
  • 19,317
  • 2
  • 60
  • 61
  • Not really.. Strong typing has its advantages, and disadvantages too... I am actually torn between the compile-time-correctness of strong typing of Java and dynamic advantages of python, groovy and the like and I easily can find situations where either of the two is better ... so I use both approaches in different situations... Adjusting my tools to the problem rather than the opposite. – Jarek Potiuk Jul 04 '11 at 22:25
  • My comment was more tongue-in-cheek than serious. Not that I agree with the "dynamic" side of the camp. – Programmer Bruce Jul 04 '11 at 22:48
  • Well even sense of humour have it's limitless advantages ;) – Jarek Potiuk Jul 04 '11 at 22:52