简体   繁体   English

无法使用GSON将复杂的json序列化为对象?

[英]Not able to serialize complex json to an object using GSON?

Below is my JSON String which I am getting back by calling from a service API. 下面是我的JSON字符串,我可以通过从服务API进行调用来返回。 I have shorten it down by having only three reportRecords for the understanding purpose. reportRecords便于理解,我仅通过三个reportRecords来缩短了时间。 In general, it might have ~500 reportRecords 通常,它可能有reportRecords

{
   "aggRecords": {
      "reportRecords": [
         {
            "min": 0,
            "max": 12,
            "avg": 0.3699187,
            "count": 246,
            "sumSq": 571,
            "stddev": 1.4779372,
            "median": 0,
            "percentileMap": {
               "95": 4
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "PostProcessing",
               "Type": "PostProcessing"
            },
            "value": 91
         },
         {
            "min": 0,
            "max": 23,
            "avg": 2.3991289E-4,
            "count": 1463031,
            "sumSq": 3071,
            "stddev": 0.045814946,
            "median": 0,
            "percentileMap": {
               "95": 0
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "ResourceContext",
               "Type": "ResourceContext"
            },
            "value": 351
         },
         {
            "min": 0,
            "max": 1209,
            "avg": 1.9203402,
            "count": 7344636,
            "sumSq": 71832774,
            "stddev": 2.4683187,
            "median": 2,
            "percentileMap": {
               "95": 4
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "Client::Sync",
               "Type": "Client::Sync"
            },
            "value": 14104200
         }
      ]
   },
   "minRecordsMap": {}
}

Now From the above JSON response, I need to extract reportRecords whose Name is Client::Sync . 现在,从上面的JSON响应中,我需要提取NameClient::Sync reportRecords Meaning, I need to extract below reportRecords from the above JSON response only. 意思是,我只需要从上述JSON响应中提取以下reportRecords

         {
            "min": 0,
            "max": 1209,
            "avg": 1.9203402,
            "count": 7344636,
            "sumSq": 71832774,
            "stddev": 2.4683187,
            "median": 2,
            "percentileMap": {
               "95": 4
            },
            "metricName": "TransactionDuration",
            "dimensions": {
               "env": "dev",
               "pool": "titan",
               "Name": "Client::Sync",
               "Type": "Client::Sync"
            },
            "value": 14104200
         }

And now I need to parse the above reportRecords for Client::Sync to below object - 现在我需要解析上述reportRecords for Client::Sync到下面的对象-

public class DataMetrics {

    private String pool;
    private String name;
    private String type;
    private String env;
    private String metricName;
    private String percentile;
    private String median;
    private String stdDev;
    private String sumSq;
    private String count;
    private String avg;
    private String max;
    private String min;

    // getters and setters here
}

So after serializing, above object should look like this - 因此,序列化后,以上对象应如下所示:

pool is titan
name is Client::Sync 
type is Client::Sync
env is dev
metricNname is TransactionDuration
95th  percentile is 4
median is 2
stdDev is 2.4683187 
sumSq is 71832774 
count is 7344636 
avg is 1.9203402
max is 1209
min is 0

I am using GSON library here and below is what I have tried so far - 我在这里和下面使用的是GSON库,到目前为止,我一直在尝试-

private static RestTemplate restTemplate = new RestTemplate();

public static void main(String[] args) {

    String jsonLine = restTemplate.getForObject("some_url", String.class);
    System.out.println(jsonLine); // here jsonLine will give me above big JSON String

    JsonElement jelement = new JsonParser().parse(jsonLine);
    JsonObject  jobject = jelement.getAsJsonObject();
    jobject = jobject.getAsJsonObject("aggRecords");
    JsonArray jarray = jobject.getAsJsonArray("reportRecords");

    Type type = new TypeToken<List<DataMetrics>>() {}.getType();
    List<DataMetrics> records = gson.fromJson(jsonArrayThatYouHave, type);      

    List<DataMetrics> result = new LinkedList<>();

    for(DataMetrics record : records){
       if(record.name.equals("Client::Sync")){
          result.add(record);
       }
    }       
}

But for some reason, some fields in the DataMetrics shows me the data but some fields are coming empty so that makes me think something is wrong in my above code or my DataMetrics class is not right? 但是由于某种原因,DataMetrics中的某些字段向我显示了数据,但是某些字段却变空了,这使我觉得上面的代码有问题或者DataMetrics类不正确吗?

Generally, for nested objects like dimensions you'll declare another POJO for it 通常,对于诸如dimensions类的嵌套对象,您将为其声明另一个POJO

class DataMetrics{
  private String min;
  private String max;
  private String avg;
  /*Insert other members*/

  private Dimensions dimensions;

  public boolean isClientSync(){
    return "Client::Sync".equals(dimensions.Name);
  }
  private class Dimensions{
    private String env;
    private String pool;
    private String Name;
  }
}

Tested: 测试:

 public void test() {

 String json = "[{\"min\": 0,\"max\": 1209,\"avg\": 1.9203402,\"count\": 7344636,\"sumSq\": 71832774,  \"stddev\": 2.4683187, \"median\": 2,\"percentileMap\": {\"95\": 4},\"metricName\": \"TransactionDuration\",\"dimensions\": {\"env\": \"dev\",\"pool\": \"titan\",\"Name\": \"Client::Sync\", \"Type\": \"Client::Sync\"},\"value\": 14104200}]";

 final Gson gson = new Gson();
 final Type type = new TypeToken<List<DataMetrics>>() {}.getType();
 final List<DataMetrics> records = gson.fromJson(json, type);

 Assert.assertTrue(records.get(0).isClientSync());
}

For percentileMap you'll want an actual map 对于percentileMap您需要一张实际地图

private Map<String, Integer> percentileMap;

Also note the member variable names should match the JSON property name exactly 还要注意,成员变量名称应与JSON属性名称完全匹配

  • stdDev => stddev stdDev => stddev
  • name => Name name => Name
  • percentile => percentileMap percentile => percentileMap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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