Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deserialize json string into object

Tags:

java

gson

{
   "LocalLocationId [id=1]":{
      "type":"folderlocation",
      "id":{
         "type":"locallocationid",
         "id":1
      },
      "parentId":{
         "type":"locallocationid",
         "id":0
      },
      "name":"Test",
      "accessibleToUser":true,
      "defaultLocation":false,
      "timezoneId":"Asia/Calcutta",
      "children":[]
   },
   "LocalLocationId [id=0]":{
      "type":"folderlocation",
      "id":{
         "type":"locallocationid",
         "id":0
      },
      "parentId":null,
      "name":"Locations",
      "accessibleToUser":false,
      "defaultLocation":false,
      "timezoneId":"Asia/Calcutta",
      "children":[{
         "type":"locallocationid",
         "id":1
      }]
   },
   "allAllowedChildren":[{
      "type":"locallocationid",
      "id":1
   }]
}

How to deserialize above string into java object.

Class im using is

public class Tree {

    @SerializedName("allAllowedChildren")
    private List<Id> allAllowedChildren;

    @SerializedName("LocalLocationId")
    private Map<String, LocalLocationId> localLocationId;

    public class LocalLocationId {
        @SerializedName("type")
        private String type;

        @SerializedName("name")
        private String name;

        @SerializedName("accessibleToUser")
        private boolean accessibleToUser;

        @SerializedName("defaultLocation")
        private boolean defaultLocation;

        @SerializedName("timezoneId")
        private String timezoneId;

        @SerializedName("id")
        private Id id;

        @SerializedName("parentId")
        private Id parentId;

        @SerializedName("children")
        private List<Id> children;

        public String getType() {
            return type;
        }
        public String getName() {
            return name;
        }
        public boolean isAccessibleToUser() {
            return accessibleToUser;
        }
        public boolean isDefaultLocation() {
            return defaultLocation;
        }
        public String getTimezoneId() {
            return timezoneId;
        }
        public Id getId() {
            return id;
        }
        public Id getParentId() {
            return parentId;
        }
        public List<Id> getChildren() {
            return children;
        }
    }

    public class Id {
        private String type;
        private Integer id;

        public String getType() {
            return type;
        }
        public Integer getId() {
            return id;
        }
    }

    public List<Id> getAllAllowedChildren() {
        return allAllowedChildren;
    }
    public Map<String, LocalLocationId> getLocalLocationId() {
        return localLocationId;
    }
}
like image 374
Kedar Javalkar Avatar asked Apr 18 '26 09:04

Kedar Javalkar


1 Answers

@Kedar

I'll assume you are in control of how the JSON input string is created. I think the JSON string is not formatted correctly for default GSON deserialization of Map types.

I have modified the input string for your consideration and this results in a non null LocalLocationId

{
   "LocalLocationId":[
   [
     "1",
       {
          "type":"folderlocation",
          "id":{
             "type":"locallocationid",
             "id":1
          },
          "parentId":{
             "type":"locallocationid",
             "id":0
          },
          "name":"Test",
          "accessibleToUser":true,
          "defaultLocation":false,
          "timezoneId":"Asia/Calcutta",
          "children":[]
       }
   ],
   [
     "2",
       {
          "type":"folderlocation",
          "id":{
             "type":"locallocationid",
             "id":0
          },
          "parentId":null,
          "name":"Locations",
          "accessibleToUser":false,
          "defaultLocation":false,
          "timezoneId":"Asia/Calcutta",
          "children":[{
             "type":"locallocationid",
             "id":1
          }]
       }
   ]
   ],
   "allAllowedChildren":[{
      "type":"locallocationid",
      "id":1
   }]
}

Please comment if my assumption about the input string is incorrect.

EDIT 1: Since input cannot be modified, consider writing custom Deserializer. Below is the way to register custom deserialisation class

GsonBuilder gsonb = new GsonBuilder();
        gsonb.registerTypeAdapter(Tree.class, new TreeDeserializer());
        Gson gson = gsonb.create();

Below is the TreeDeserializer

public class TreeDeserializer implements JsonDeserializer<Tree> {

    public Tree deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {
        Tree out = new Tree();

        if (json != null) {
            JsonObject obj  = json.getAsJsonObject();
            Set<Map.Entry<String,JsonElement>> entries = obj.entrySet();
            for (Map.Entry<String, JsonElement> e: entries) {
                if (e.getKey().equals("allAllowedChildren")) {
                    Type ft = List.class;
                    System.out.println(context.deserialize(e.getValue(), ft));
                    // TODO add this back into the Tree out object
                } else {
                    // LocalLocationId
                    System.out.println(e.getKey());
                    System.out.println(context.deserialize(e.getValue(), Tree.LocalLocationId.class));

                    // TODO add this back into the Tree out object
                }
            }
        } 
        return out;
    }

}

Here is the console output from the Sysouts.

LocalLocationId [id=1]
org.test.StackOverflowAnswers.Tree$LocalLocationId@464bee09
LocalLocationId [id=0]
org.test.StackOverflowAnswers.Tree$LocalLocationId@f6c48ac
[{type=locallocationid, id=1.0}]
org.test.StackOverflowAnswers.Tree@589838eb

I have left TODOs in the deserialiser where you'll need to write custom code to inject the values from deserialisation into the Tree class just created. Hope this helps. Can't provide full implementation, but I think this would be a partial solution

like image 87
vvs Avatar answered Apr 20 '26 00:04

vvs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!