Json反序列化用于Java中的异构类型Json

huangapple go评论62阅读模式
英文:

Json Deserialize for hetero-type json Java

问题

抱歉提前说一声,我对JSON解析还有点新,我在Java中解析对象中的JSON时遇到了问题。

{
  "result": {
    "City": {
      "Delhi": {
        "A-Hospital": {
          "pincode": 400001
        },
        "B-Hospital": {
          "pincode": 400002
        },
        "C-Hospital": {
          "pincode": 400003
        },
        ...
      },
      "Mumbai": {
        "A-Hospital": {
          "pincode": 500001
        },
        "B-Hospital": {
          "pincode": 500002
        },
        "C-Hospital": {
          "pincode": 500003
        },
        ...
      },
      "Bangalore": {
        "A-Hospital": {
          "pincode": 600001
        },
        "B-Hospital": {
          "pincode": 600002
        },
        "C-Hospital": {
          "pincode": 600003
        },
        "D-Hospital": {
          "pincode": 600004
        },
        ...
      }
    }
  }
}

从第三方那里接收到的JSON,所以无法保证格式。
如何为这种动态JSON创建类结构,并解析为对象?

class City {
  private Map<String, Map<String, Hospital>> hours;
  // Getter和Setter
}

class Hospital {
  private String pincode;
  // Getter和Setter
}

我想要形成一个以城市为键,医院(A-Hospital、B-Hospital等)为对象的Map。
例如:Map<String, Hospital> cityHospitalMapping。
class Hospital {
  String HospitalName;
  Integer pincode;
}

但是如何编写反序列化程序?
尝试过:

JsonObject allcities = (JsonObject) json.get("result");
City cities = new Gson().fromJson(allcities, City.class);

但是 cities 不包含任何数据。

结果:
cities{pincode=null}
英文:

Apologies in advance, I'm a little new to JSON parsing and I m facing a problem in parsing JSON in Object in java.

{ result: {
&quot;City&quot;: {
&quot;Delhi&quot;: {
&quot;A-Hospital&quot;: {
&quot;pincode&quot;: 400001
},
&quot;B-Hospital&quot;: {
&quot;pincode&quot;: 400002
},
&quot;C-Hospital&quot;: {
&quot;pincode&quot;: 400003
},
.
.
.
},
&quot;Mumbai&quot;: {
&quot;A-Hospital&quot;: {
&quot;pincode&quot;: 500001
},
&quot;B-Hospital&quot;: {
&quot;pincode&quot;: 500002
},
&quot;C-Hospital&quot;: {
&quot;pincode&quot;: 500003
},
.
.
.
},
&quot;Bangalore&quot;: {
&quot;A-Hospital&quot;: {
&quot;pincode&quot;: 600001
},
&quot;B-Hospital&quot;: {
&quot;pincode&quot;: 600002
},
&quot;C-Hospital&quot;: {
&quot;pincode&quot;: 600003
},
&quot;D-Hospital&quot;: {
&quot;pincode&quot;: 600004
},
.
.
.
}
}
}
}

Receiving Json is received from 3rd person hence can't the format.
How to create the class structure for such dynamic json and parse into Object ?

class City{
private Map&lt;String, Map&lt;String,Hospital&gt;&gt; hours;
//Getter and Setter
}
class Hospital {
private String pincode;
//Getter and Setter
}

I want to form a Map of the City with Hospital(A-Hospital,B-Hospital,etc) as Object. Example: Map<String,Hospital> cityHospitalMapping. class Hospital { String HospitalName; Integer pincode; }

But How to write the Deserializer ?
Tried

JsonObject allcities = (JsonObject) json.get(&quot;result&quot;);
City cities = new Gson().fromJson(allcities,City.class);

But cities is not containing any data.

Result:
cities{pincode=null}

答案1

得分: 1

已编辑,因为您在 JSON 中添加了 result。您在此次编辑后的问题是,您声明的 City 不包含但它本身就是一个 Map<String, Map<String, Hospital>>

首先,您需要一个“包装”类,称为 Data。这是因为您的 JSON 示例有一个包含 Response 的对象,而该 Response 包含 City
对于 City,没有固定的字段名称,因此您需要将其反序列化为 Map

相同的方法适用于City中保存的值City 中的值也是 Map 类型,我们称这些值为内部映射。由于存在一个固定的字段名称 pincode,您可以在此内部映射中将前面提到的值声明为类型为 Hospital,从而得到一个类似这样的类:

@Getter @Setter
public class Data {
    @Getter @Setter
    public class Result {
        private Map<String, Map<String, Hospital>> City;
        @Getter @Setter
        public class Hospital {
            private String pincode;
        }
    }
    private Result result;
}

现在,如果您使用上述类使用 Gson 进行反序列化,您可以这样使用:

Data data = gson.fromJson(JSON, Data.class);
Map<String, Map<String, Hospital>> city = data.getResult().getCity();

并获得 400002

您可以实现一些更或更少复杂的自定义反序列化器,但也许直接按原样反序列化 JSON,然后根据需要将其映射到其他类型的类会更容易一些。

英文:

Edited because you added the result in your JSON. Your problem here - after edit - is that City you declared does not contain but it itself IS a Map&lt;String, Map&lt;String,Hospital&gt;&gt;.

First of all you need a "wrapper" class, say Data. That is because your JSON example has an object that contains Response that contains City.
For City, there are no fixed field names so you need to deserialize it as a Map.

The same applies to values held in the map City. Values in City are also type of Map let us call these values inner map. Because there is this one fixed field name pincode you can declare before mentioned values in this inner map as of type Hospital, leading to a class like:

@Getter @Setter
public class Data {
@Getter @Setter
public class Result {
private Map&lt;String, Map&lt;String, Hospital&gt;&gt; City;
@Getter @Setter
public class Hospital {
private String pincode;
}
}
private Result result;
}

Now if you deserialize with Gson using this above class you can use it like:

Data data = gson.fromJson(JSON, Data.class);
Map&lt;String, Map&lt;String, Hospital&gt;&gt; city = data.getResult().getCity();

and obtain 400002.

You could implement some more or less complex custom deserializer but maybe it is more easy to deserialize JSON as it is and after tath do some mappings to other types of classes if needed.

huangapple
  • 本文由 发表于 2020年10月15日 17:21:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/64368481.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定