0

I am trying to fetch json response using retrofit 2. My json response looks like this :

[
    0 : {
        type : "video",
        format : "mp4",
        size : "10mb"
        },
    1 : {
        type : "audio",
        format : "mp3",
        size : "10mb"
        },
    2 : {
        type : "text",
        format : "pdf",
        size : "10mb"
        }
]

How should my model class look like? I can't understand as it has dynamic keys.

6
  • What library are you using to parse? gson? jackson? anyways, that is an array, so parsing it to an array of a class (that has type, format and size) should be straight forward. Commented Aug 7, 2017 at 7:17
  • I am using gson Commented Aug 7, 2017 at 7:28
  • as they already said, the json is invalid, once is valid, you shouldn't have any issues to parse it. Im attaching an example below Commented Aug 7, 2017 at 7:45
  • Your example doesn't have dynamic keys, but, if it did, you could look at stackoverflow.com/questions/36780871/… Commented Aug 7, 2017 at 17:52
  • @EricCochran, I meant different keys . Here it has 0,1,2. Commented Aug 7, 2017 at 18:01

3 Answers 3

5

This is not a valid Json as you can try that on https://jsonlint.com/ , you can change your response to :

[  
   {  
      "type":"video",
      "format":"mp4",
      "size":"10mb"
   },
   {  
      "type":"audio",
      "format":"mp3",
      "size":"10mb"
   },
   {  
      "type":"text",
      "format":"pdf",
      "size":"10mb"
   }
]
Sign up to request clarification or add additional context in comments.

Comments

3

first of all this is invalid/incomplete JSON. The valid version would look something like this

{
  "items": [
    {
      "0": {
        "type": "video",
        "format": "mp4",
        "size": "10mb"
      }
    },
    {
      "1": {
        "type": "audio",
        "format": "mp3",
        "size": "10mb"
      }
    },
    {
      "2": {
        "type": "text",
        "format": "pdf",
        "size": "10mb"
      }
    }
  ]
}

and it would safely deserialize to this

    class Item{
        String type;
        String format;
        String size;
    }

    class Response{
        List<Map<Integer,Item>> items;
    }


//....

Response response = new Gson().fromJson(yourJson, Response.class);

As an alternative solution, as I am sure you can't change the JSON format, change the [] to {} in your JSON string and deserialize it like this

Map fieldMap = (Map)new Gson().fromJson(json, Map.class);

it should give you a LinkedTreeMap of all your data

8 Comments

Why a list of maps?, the json should be more simple, like the one presented by @Arash. Response should be a List of Item.
I'm not sure 0:{something} works like list.add(0,something) in GSON. ":" usually means key/value. ["1","2","3"] : this surely does deserialize into a valid java list.
but if you are changing the json to make it valid, you can change that...
@MatiasOlocco in some situations one can't change the remote WS to fit one's requirements (public API, 3rd party lib, no access, bad devs). At this point, a small client-side change of first and last chars in the JSON string is almost acceptable, provided that you can easily work with it afterwards and it helps you avoid useless boxings in the code. Changing it to the fully correct version of it (my first example or other answers) isn't something would/could do from the client code. so yes, if I couldn't change the remote JSON source, I would go for [ ] to { } and turn it into a Map<Item>
I know that.. but you changed the json entirely.., and you stated how a valid version should look, and then your valid version is not optimal, that was my whole point, if you get to change the json, why doing it like in your example when it can be done in a better way. Sorry, but it is like that.
|
2

So, as people already said, if you change your json to be valid:

[  
   {  
      "type":"video",
      "format":"mp4",
      "size":"10mb"
   },
   {  
      "type":"audio",
      "format":"mp3",
      "size":"10mb"
   },
   {  
      "type":"text",
      "format":"pdf",
      "size":"10mb"
   }
]

Then you can create your class, for instance:

public class Test {
    public String type;
    public String format;
    public String size;
}

And then, with Gson:

Type testType = new TypeToken<ArrayList<Test>>(){}.getType();
ArrayList<Test> list = new Gson().fromJson(json, testType);

On the other hand, with retrofit2 you can get the Gson converter to do the job for you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.