【问题标题】:How to deserialize json string into object如何将json字符串反序列化为对象
【发布时间】:2015-09-30 07:45:50
【问题描述】:
{
   "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
   }]
}

如何将上面的字符串反序列化为java对象。

类 im 使用 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;
    }
}

【问题讨论】:

  • 你遇到了什么错误?
  • 将上面的字符串反序列化为java对象是不可能用你现在使用的类来做的。
  • @RyanFung 需要详细说明吗?我猜 OP 不知道为什么会这样。
  • @dotvav.,在 Tree tree = gson.fromJson(locationTree, Tree.class); 之后,我得到 LocalLocationId 为 null
  • @RyanFung 如果需要可以更改树类结构

标签: java gson


【解决方案1】:

@Kedar

我假设您可以控制 JSON 输入字符串的创建方式。 我认为对于 Map 类型的默认 GSON 反序列化,JSON 字符串的格式不正确。

我已修改输入字符串以供您考虑,这会导致 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
   }]
}

如果我对输入字符串的假设不正确,请发表评论。

编辑 1: 由于无法修改输入,请考虑编写自定义反序列化器。 下面是注册自定义反序列化类的方法

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

下面是 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;
    }

}

这是 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

我已将 TODO 留在了反序列化器中,您需要编写自定义代码将反序列化的值注入刚刚创建的 Tree 类。希望这可以帮助。无法提供完整的实现,但我认为这将是部分解决方案

【讨论】:

  • json 字符串是从第三方 api 接收的,与我提到的格式完全相同
  • 好的,那么我可以看到唯一的选择是编写自己的代码来执行部分反序列化
  • 我已经做了类似的事情来将字符串解析成Tree 类..我一定会试试你的方法..干杯....
【解决方案2】:

用户 JSONParser 更快。

以下是示例。如果你用谷歌搜索,可能会有一个更好的例子。希望这会有所帮助。

JSONParser parser=new JSONParser();
System.out.println("=======decode=======");
String s="[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]";  
Object obj=parser.parse(s);  
JSONArray array=(JSONArray)obj;  
System.out.println("======the 2nd element of array======");  
System.out.println(array.get(1));  
System.out.println();                  
JSONObject obj2=(JSONObject)array.get(1);  
System.out.println("======field \"1\"==========");  
System.out.println(obj2.get("1"));                      
s="{}";  
obj=parser.parse(s);  
System.out.println(obj);                  
s="[5,]";  
obj=parser.parse(s);  
System.out.println(obj);                  
s="[5,,2]";  
obj=parser.parse(s);  
System.out.println(obj);

【讨论】:

    【解决方案3】:

    你可以使用 Gson ..

    String json = "Your json string "
    Tree treeObj= new Gson().fromJson(json, Tree .class);
    

    【讨论】:

    • 将上述结果运行到 null 以获取 localLocationId 地图
    • 我可以看到你需要修改你的 json 字符串,它的格式不正确。
    【解决方案4】:

    您可以使用 Jackson 的 ObjectMapper -

    Tree deserializedTree = new ObjectMapper().readValue(jsonStringOfTree, Tree.class);
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      • 2020-02-03
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      相关资源
      最近更新 更多