2

I'm working on a personal project in Android and I want to use GSON to parse a JSON file containing the data I need. I have a local JSON file with the following structure:

{
  "Object1": {
    "foo": "value1",
    "bar": "value2",
    "baz": "value3",
    ...
  },
  "Object2": {
    "foo": "value4",
    "bar": "value5",
    "baz": "value6",
    ...
  },
  ...
 }

I have already made an Object class of the following structure:

Class Object {
  String data;
  ...
}

How would I parse this JSON file with this structure?

EDIT: The JSON file I use is very large, it contains about 400+ of these objects of type Object. I would have to iterate over each object to create a new JSONObject, but I do not know how to do this.

Rick
  • 31
  • 10
  • Use http://www.jsonschema2pojo.org/ – Raj Jul 03 '18 at 14:53
  • Thank you for your comment, however, this is not exactly what i was looking for. Also, the JSON file I use is very large, therefore I can't use this tool. – Rick Jul 03 '18 at 15:00
  • you mean somethink like this? https://stackoverflow.com/a/17810270/8035924 – Giulio Pettenuzzo Jul 03 '18 at 15:09
  • Thank you for your comment, but I don't think this is of much use either. I would have to manually create over 400 objects. I want to be able to use GSON to parse the JSON file. (See edited question) – Rick Jul 03 '18 at 15:18
  • Here's the JSON file i'm using: https://github.com/rickteuthof/SJTool/blob/master/app/src/main/assets/demon-data.json – Rick Jul 03 '18 at 15:19
  • As all your objects have the same structure you can create only one class. Then parse your Json manually. For every objects in your Json you then use Gson to deserialise them automatically into to you class type. So at the end you have a list of objects of your custom class – Eselfar Jul 03 '18 at 15:49
  • Could you perhaps explain this in more detail in an answer so I could accept it? Thank you very much. – Rick Jul 03 '18 at 16:09

1 Answers1

3

In the solution below, we convert the JSON you've provided in your link as a JSONOject. Then we get the list of names contained in the JSON ("Abaddon", "Archeri", ...). Once we have the list we iterate through it. For each name we get the JSON object associated with it.

Then we use GSON to convert each object into a Demon object. The Demon class has been generated using http://www.jsonschema2pojo.org/ as suggested above.

As all the objects in the JSON have the same structure we need only one class to deserialize every single one of them.

Deserializer

public List<Demon> deserialize(String json) {
    try {
        JSONObject jsonObject = new JSONObject(json);


        final JSONArray names = jsonObject.names();
        final List<Demon> demons = new ArrayList<>();
        final Gson gson = new Gson();
        Demon demon;
        for (int i = 0; i < names.length(); i++) {
            demon = gson.fromJson(jsonObject.get(names.getString(i)).toString(), Demon.class);
            demons.add(demon);
        }

        return demons;

    } catch (JSONException e) {
        e.printStackTrace();
        return null;
    }
}

Demon class

public class Demon {

    @SerializedName("ailments")
    @Expose
    public String ailments;

    @SerializedName("align")
    @Expose
    public String align;

    @SerializedName("code")
    @Expose
    public Integer code;

    @SerializedName("inherits")
    @Expose
    public String inherits;

    @SerializedName("lvl")
    @Expose
    public Integer lvl;

    @SerializedName("pcoeff")
    @Expose
    public Integer pcoeff;

    @SerializedName("race")
    @Expose
    public String race;

    @SerializedName("resists")
    @Expose
    public String resists;

    @SerializedName("skills")
    @Expose
    public List<String> skills = null;

    @SerializedName("source")
    @Expose
    public List<String> source = null;

    @SerializedName("stats")
    @Expose
    public List<Integer> stats = null;

    public Demon(){
        // Default constructor
    }
}
Eselfar
  • 3,759
  • 3
  • 23
  • 43
  • Thank you very much! This will certainly be of much help. – Rick Jul 03 '18 at 16:15
  • You're welcome. I've added some text to help you understand it – Eselfar Jul 03 '18 at 16:17
  • If you want to keep the Demon's name you can add an extra name field to the Demon class. Then in the loop you do `String name = names.getString(i)).toString();` and you then add it manually to the Demon `demon.setName(name);` Easy ;) – Eselfar Jul 03 '18 at 16:24
  • 1
    Thank you! I was initially thinking about making it a hashmap instead of a list, so i can access the data of each demon quickly. – Rick Jul 03 '18 at 22:22
  • It depends on what you want to do with the data, but yeah, I agree, in that case a Map is a good idea. – Eselfar Jul 04 '18 at 08:37
  • I don't know what you want to do but if you need these exact same data every time the user launches the app, it could be a good idea to use a database instead of parsing the JSON, as it is quite big. You can still parse the JSON the very first time to init the db – Eselfar Jul 04 '18 at 08:45
  • Well it's supposed to be a database app for a game, but I want it to be easily accessible and usable without an internet connection. I agree this might not be the best solution for this specific situation but currently the information i need is only in the form of the JSON file I have. – Rick Jul 04 '18 at 12:01
  • You don't need to have a server. You can have a local database. Have a look at [Room](https://developer.android.com/topic/libraries/architecture/room) – Eselfar Jul 04 '18 at 12:32
  • The benefit of having a database is: 1. You don't need to parse the JSON every time the user launches the app. 2. You don't use a lot of memory (RAM) to keep objects you don't use. You only have the ones you want in memory and the rest of the data is on the storage, in the database. – Eselfar Jul 04 '18 at 12:35
  • Thank you, this has been a great help. I've fixed my problem somewhat, with my find and replace skills i managed to make a better json file which would make parsing it a lot easier! – Rick Jul 04 '18 at 14:34