Parse Complex of JSON

Asked

Viewed 1,459 times

2

I am trying to parse a JSON, using GSON, but there is a complex part, because I don’t know the name of Keys, so I don’t know what name I should use in the variables for GSON to parse. I researched and it seems that I have to use Map<>, but I’m not even able to do it.

Example JSON:

{
  "type": "typeString",
  "format": "json",
  "version": "4.13.35",
  "data": {
    "data1": {
      "version": "4.13.1",
      "id": "data1",
      "key": "238",
      "name": "John"
    },
    "data2": {
      "version": "4.13.1",
      "id": "data2",
      "key": "115",
      "name": "Hello"
    },
    "data3": {
      "version": "4.13.1",
      "id": "date3",
      "key": "26",
      "name": "Zeus"
    },
    "data4": {
      "version": "4.13.1",
      "id": "data4",
      "key": "143",
      "name": "Venus"
    }
  }
}

Made class:

public class MasterGSON {

    @SuppressWarnings("type")
    private String type;

    @SuppressWarnings("format")
    private String format;

    @SuppressWarnings("version")
    private String version;

    @SuppressWarnings("data")
    private Map<String, DataGSON> listChampion;

    public Map<String, DataGSON> getListChampion() {
        return listChampion;
    }

    public String getType() {
        return type;
    }

    public String getFormat() {
        return format;
    }

    public String getVersion() {
        return version;
    }

    public class DataGSON {


        private String version;

        private String id;

        private String key;

        private String name;


        public String getVersion() {
            return version;
        }

        public String getId() {
            return id;
        }

        public String getKey() {
            return key;
        }

        public String getName() {
            return name;
        }
    }
}

Can someone help me?

  • Kiotto, include the code you have already done, as the question is very wide. How come you do not know the keys? Would the attributes of JSON not? Can these attributes that are in the example JSON change? That I know GSON can fill its class using Reflection in the fields.

  • The code I made was the one on top, then I do: Gson gsonaux = new Gsonbuilder(). create(); Mastergson aux = gsonaux.fromJson(json, Mastergson.class); The variables type, format, version come with data, listChampion comes null... I don’t know the Keys data1, data2, data3... These Keys can change and can have N Keys

  • Hey, Kiotto, when people have questions about your question, you better [Edit] the question to clarify things. It is confusing if you put this kind of thing in the comments.

3 answers

3


GSON does Parsing correctly if the field name is equal to JSON. Because it uses Reflection to deserialize the nested object.

The attribute listChampion stays null because it makes a direct association of JSON keys with its object. It finds the key data and by Reflection searches for an attribute with name data in your class MasterGSON. Then he checks the type, and deserializes according to the type. In the case of Map, no matter the name of the keys, what will matter is the internal structure of the object DataGSON.

Just changing the attribute name of listChampion for data, but keeping the Map<String, DataGSON> he deserializes properly.

The class would be:

public class MasterGSON {

    @SuppressWarnings("type")
    private String type;

    @SuppressWarnings("format")
    private String format;

    @SuppressWarnings("version")
    private String version;

    @SuppressWarnings("data")
    private Map<String, DataGSON> data;

    public Map<String, DataGSON> getListChampion() {
        return data;
    }

    // Demais getters/setters
}

To deserialize the JSON I did so:

GsonBuilder gsonBuilder = new GsonBuilder();
MasterGSON gs = gsonBuilder.create().fromJson(json, MasterGSON.class);

In his Map<String, DataGSON>, where each element is a key pair/value of its object data. As long as the name of this object does not change, no matter the name of the keys inside it.

  • It worked :) listChampion for data.&#I had an idea that the @SuppressWarnings("data") was to put the name of the key that we are waiting for comes from JSON, but then the variable name could be with another name, after all it seems that was wrong.. Or this only happens in this specific case for Map<>?

  • The SupressWarnings is an annotation by the Java compiler not to issue warnings during compilation, it has no relation to the GSON library. I incorporated into my answer why it didn’t work, but the fact that I used Map key name flexibility for the attributes, which is in your case.

  • How stupid of me, of course SuppressWarnings doesn’t work, it’s like you said, it has nothing to do with GSON. What I was referring to was the @SerializedName, but I changed the names and because of that none of this worked. Stupidity on my side :( Sorry.. Thanks for the answers, now everything works fine :)

0

You can use the JSON Schema. Simply you pass the JSON and it returns the POJO, then you can use the GSON.

I did a test with your JSON file and these classes were returned, after generated just make a few adjustments. -----------------------------------com.example.Data.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;

@Generated("org.jsonschema2pojo")
public class Data {

@Expose
private Data1 data1;
@Expose
private Data2 data2;
@Expose
private Data3 data3;
@Expose
private Data4 data4;

public Data1 getData1() {
return data1;
}

public void setData1(Data1 data1) {
this.data1 = data1;
}

public Data2 getData2() {
return data2;
}

public void setData2(Data2 data2) {
this.data2 = data2;
}

public Data3 getData3() {
return data3;
}

public void setData3(Data3 data3) {
this.data3 = data3;
}

public Data4 getData4() {
return data4;
}

public void setData4(Data4 data4) {
this.data4 = data4;
}

}
-----------------------------------com.example.Data1.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;

@Generated("org.jsonschema2pojo")
public class Data1 {

@Expose
private String version;
@Expose
private String id;
@Expose
private String key;
@Expose
private String name;

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
-----------------------------------com.example.Data2.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;

@Generated("org.jsonschema2pojo")
public class Data2 {

@Expose
private String version;
@Expose
private String id;
@Expose
private String key;
@Expose
private String name;

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
-----------------------------------com.example.Data3.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;

@Generated("org.jsonschema2pojo")
public class Data3 {

@Expose
private String version;
@Expose
private String id;
@Expose
private String key;
@Expose
private String name;

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
-----------------------------------com.example.Data4.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;

@Generated("org.jsonschema2pojo")
public class Data4 {

@Expose
private String version;
@Expose
private String id;
@Expose
private String key;
@Expose
private String name;

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
-----------------------------------com.example.Example.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;

@Generated("org.jsonschema2pojo")
public class Example {

@Expose
private String type;
@Expose
private String format;
@Expose
private String version;
@Expose
private Data data;

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getFormat() {
return format;
}

public void setFormat(String format) {
this.format = format;
}

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public Data getData() {
return data;
}

public void setData(Data data) {
this.data = data;
}

}
  • The problem is that I do not know the name of the Keys data1, data2... I put these names as examples. And besides not knowing these names, there may be N of these Keys.

  • @Kiotto, @Douglas. I’m not familiar with the GSON library, but cannot retrieve Object data and iterate on his keys and "parse" the object of that key?

  • I get it, so you can’t use GSON, you have to do it in your hand anyway, whenever you find a main knot you’ll have to sweep it... I’ll see if I can find an example.

  • Why don’t you write a JsonDeserializer for that object?

0

Since the JSON schema is not static, you can use the JSON "DOM" that GSON offers (classes from package com.google.gson: Jsonobject, Jsonarray, Jsonprimitive, Jsonnull, Jsonelement) - Instead of trying to deserialize JSON to the type, you would deal directly with the JSON structure. Something similar to the code below:

JsonObject root = new JsonParser().parse(JSON).getAsJsonObject();
JsonObject data = root.get("data").getAsJsonObject();
for (Entry<String, JsonElement> property : data.entrySet()) {
    String propName = property.getKey();
    JsonElement propValue = property.getValue();
    // Faça o que quiser com o valor...
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.