简体   繁体   中英

Get nested JSON object with GSON : Deserialization

I have gone through the threads from SOF which talks about getting nested JSON using GSON. Link 1 Link 2 . My JSON file is as shown below

{
   "Employee_1": {
      "ZipCode": 560072,
      "Age": 50,
      "Place": "Hawaii",
      "isDeveloper": true,
      "Name": "Mary"
   },
   "Employee_2": {
      "ZipCode": 560072,
      "Age": 80,
      "Place": "Texas",
      "isDeveloper": true,
      "Name": "Jon"
   }
}

my classes are as shown below

public class Staff {

    String Employee_1 ; 
}

class addnlInfo{
    String Name;
    String Place;
    int Age;
    int Zipcode;
    boolean isDeveloper;
}  

The deserializer class which I built is as shown below

class MyDeserializer implements JsonDeserializer<addnlInfo>{

    public addnlInfo deserialize1(JsonElement je, Type type, JsonDeserializationContext jdc)
        throws JsonParseException
    {
        // Get the "content" element from the parsed JSON
        JsonElement content = je.getAsJsonObject().get("Employee_1");

        // Deserialize it. You use a new instance of Gson to avoid infinite recursion
        // to this deserializer
        return new Gson().fromJson(content, addnlInfo.class);

    }

    @Override
    public TokenMetaInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        // TODO Auto-generated method stub
        return null;
    }

The main file

Gson gson = new GsonBuilder()
                .registerTypeAdapter(addnlInfo.class, new MyDeserializer())
                .create();

String jsonObject=  gson.toJson(parserJSON);
addnlInfo info= gson.fromJson(jsonObject, addnlInfo .class);
System.out.println(info.Age + "\n" + info.isDeveloper + "\n" + info.Name + "\n" + info.Place);


Staff parentNode = gson.fromJson(jsonObject, Staff.class);
System.out.println(parentNode.Employee_1);

The problem:

My Subparent element (eg 'Employee_1') keeps changing. Do I have to construct multiple deserializers?

Also, I get "Expected a string but was BEGIN_OBJECT" which I understand as we use nestedJSON.

I am not sure how your classes translate to your JSON, but you are making this too complex.

I renamed fields and class names to adhere to Java standards.

Main.java

import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

public class Main {
    public static void main(String[] args) {
        Map<String, Staff> employees = new LinkedHashMap<String, Staff>();
        employees.put("Employee_1", new Staff(new Info("Mary", "Hawaii", 50, 56072, true)));
        employees.put("Employee_2", new Staff(new Info("Jon",  "Texas",  80, 56072, true)));

        String jsonString = new GsonBuilder().setPrettyPrinting().create().toJson(employees);
        System.out.println("# SERIALIZED DATA:");
        System.out.println(jsonString);

        Type mapOfStaff = new TypeToken<Map<String, Staff>>() {}.getType();
        Map<String, Staff> jsonObject = new Gson().fromJson(jsonString, mapOfStaff);
        System.out.println("\n# DESERIALIZED DATA:");
        for (Entry<String, Staff> entry : jsonObject.entrySet()) {
            System.out.printf("%s => %s%n", entry.getKey(), entry.getValue());
        }
    }
}

Staff.java

public class Staff {
    private Info info;

    public Staff(Info info) {
        this.info = info;
    }

    public Info getInfo() {
        return info;
    }

    public void setInfo(Info info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return String.format("Staff [info=%s]", info);
    }
}

Info.java

public class Info {
    private String name;
    private String place;
    private int age;
    private int zipcode;
    private boolean developer;

    public Info(String name, String place, int age, int zipcode, boolean developer) {
        this.name = name;
        this.place = place;
        this.age = age;
        this.zipcode = zipcode;
        this.developer = developer;
    }

    public String getName() {
        return name;
    }

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

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getZipcode() {
        return zipcode;
    }

    public void setZipcode(int zipcode) {
        this.zipcode = zipcode;
    }

    public boolean isDeveloper() {
        return developer;
    }

    public void setDeveloper(boolean developer) {
        this.developer = developer;
    }

    @Override
    public String toString() {
        return String.format(
            "Info [name=%s, place=%s, age=%d, zipcode=%d, developer=%b]",
            name, place, age, zipcode, developer
        );
    }
}

Output

# SERIALIZED DATA:
{
  "Employee_1": {
    "info": {
      "name": "Mary",
      "place": "Hawaii",
      "age": 50,
      "zipcode": 56072,
      "developer": true
    }
  },
  "Employee_2": {
    "info": {
      "name": "Jon",
      "place": "Texas",
      "age": 80,
      "zipcode": 56072,
      "developer": true
    }
  }
}

# DESERIALIZED DATA:
Employee_1 => Staff [info=Info [name=Mary, place=Hawaii, age=50, zipcode=56072, developer=true]]
Employee_2 => Staff [info=Info [name=Jon, place=Texas, age=80, zipcode=56072, developer=true]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM