0

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 (e.g. '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.

1 Answer 1

1

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]]
Sign up to request clarification or add additional context in comments.

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.