0

I'm using GSON for parsing JSON response.

Unfortunately the WebApi on the server has quite untypical JSON objects.

I need to parse Attachments array from this JSON (there can be more attachments):

{"htmlMessage":"text","Attachments":{"8216096_0":{"content":null,"filename":"plk.jpg","contentType":"image/jpeg","contentDisposition":"attachment","size":86070}}}

Where 8216096_0 is attachments id.

I can't do it with Gson (or I don't know how) so I'm trying to do it with JSONObjects:

// parse attachments
JSONObject attachmentsJson = result.getJSONObject("Attachments");

Then I have one JSONObject with an array of attachments, but I don't know how to get them to the ArrayList from JSONObject because the key value isn't static but generated id..

Thank you

//EDIT:
Thanks to all guys for helping! My final solution looks like this especially thanks to @Jessie A. Morris and his final answer!

List<AttachmentModel> attachmentsList = new ArrayList<AttachmentModel>();
for( Map.Entry<String, JsonElement> attachment : attachments.entrySet()) {
    AttachmentModel attachmentModel = new AttachmentModel();
    attachmentModel = gson.fromJson(attachment.getValue().getAsJsonObject().toString(), AttachmentModel.class);;
    attachmentModel.setmUid(attachment.getKey());
    attachmentsList.add(attachmentModel);
 }
Stepan Sanda
  • 2,322
  • 7
  • 31
  • 55

3 Answers3

2

Okay, I've changed my example a little bit and am certain that this does work correctly (I just tested it):

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by jessie on 14-07-09.
 */
public class TestGson {
    private static String JSON = "{\"htmlMessage\":\"text\",\"Attachments\":{\"8216096_0\":{\"content\":null,\"filename\":\"plk.jpg\",\"contentType\":\"image/jpeg\",\"contentDisposition\":\"attachment\",\"size\":86070}}}\n";

    public static void main(String[] args) {
        JsonObject json = new JsonParser().parse(JSON).getAsJsonObject();
        JsonObject attachments = json.getAsJsonObject("Attachments");

        List<JsonObject> attachmentsList = new ArrayList<JsonObject>();
        for( Map.Entry<String, JsonElement> attachment : attachments.entrySet()) {
            attachmentsList.add(attachment.getValue().getAsJsonObject());
        }

        System.out.println("attachmentsList at the end? " + attachmentsList);
    }
}
Jessie A. Morris
  • 2,267
  • 21
  • 23
  • Ok thank you, but it doesn't work neither.. on line `attachmentsList.add(attachmentsJson.get(key))` returns Object instead of JSONObject and then when I fix it to `getJSONObject` it says that `attachmentsJson` foreach not applicable to type 'java.util.Iterator' – Stepan Sanda Jul 09 '14 at 14:10
1

I'm not completely sure if this really works:

final Map<String,JSONObject> attachmentsJson = (Map<String,JSONObject>) jsonArray.getJSONObject("Attachments");
for(String attachmentId : attachmentsJson.keySet()) {
  final JSONObject attachmentJson = attachmentsJson.get(attachmentId);
}
nyx
  • 477
  • 1
  • 4
  • 10
  • Thank yo. I like your solution but unfortunately I'm getting an exception: `java.lang.ClassCastException: org.json.JSONObject cannot be cast to java.util.Map` on first line where you are trying to cast JSON to Map – Stepan Sanda Jul 09 '14 at 13:54
  • ok, then this is the wrong answer. See @Jessie A. Morris for the right answer. – nyx Jul 09 '14 at 14:06
0

The "Attachments" obj in your example is not an array.

Json arrays are denoted by [....].

"Attachments" is a Json object holding an inner object called "8216096_0".

so to get the inner values do as follows:

JSONObject attachmentsJson = result.getJSONObject("Attachments");
JSONObject inner = attachmentsJson.getJSONObject("8216096_0");

// and interrogate the inner obj:
String content = inner.getString("content");
String filename = inner.getString("filename");


Finally, and for example sake, I will add the code for processing a (real) Json array:

{"htmlMessage":"text",
   "Attachments":[{"8216096_0":{"content":null,"filename":"plk.jpg","contentType":"image/jpeg",
                  "contentDisposition":"attachment","size":86070}},                  
                 {"8216096_1":{"content":null,"filename":"plk.jpg","contentType":"image/jpeg",
                    "contentDisposition":"attachment","size":86070}},  
              ]
   }


It will go like this:

JSONArray attachmentsJson = result.getJSONObject("Attachments");
int len = attachmentsJson.length();
for (int i = 0; i < len; i++) {
    JSONObject elem =  attachmentsJson.getJSONObject(i); // <------ get array element 
    JSONObject inner = elem.getJSONObject("8216096_0");   
    // and interrogate the inner obj:
    String content = inner.getString("content");
    String filename = inner.getString("filename");
}

..Or similar, depending on your Json's exact format.

Gilad Haimov
  • 5,767
  • 2
  • 26
  • 30
  • Yes, you are right.. But there can be more attachments in others emails, so I have to solve it differently – Stepan Sanda Jul 09 '14 at 13:43
  • Thank you, unfortunately I have problem with `attachmentsJson.getJSONObject(i);` the getJSONObject(String) instead of int i... or am I missing something? And I don't understand to this: `elem.getJSONObject("8216096_0");` how can u use 8216096_0 which I don't know at this time? – Stepan Sanda Jul 09 '14 at 14:43