2014-06-20 111 views
0

下面是我通過從服務API調用回來的JSON字符串。爲了理解目的,我只用了三個reportRecords來縮短它。一般情況下,它可能有5〜50 reportRecords無法使用GSON將複雜的json序列化爲對象?

{ 
    "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": {} 
} 

現在從上面的JSON響應,我需要提取reportRecordsNameClient::Sync。意思是,我只需要從上面的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 
     } 

現在我需要爲Client::Sync上述reportRecords解析以下對象 -

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 
} 

所以經過序列化,上述目的應該是這樣的 -

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 

我使用這裏和下面的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); 
     } 
    }  
} 

但由於某些原因,DataMetrics中的某些字段會向我顯示數據,但某些字段會變空,以至於使我認爲上述代碼中存在某些錯誤,或者我的DataMetrics類不正確?

回答

1

一般來說,像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; 
    } 
} 

測試:

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()); 
} 

percentileMap,你會希望有一個實際的地圖

private Map<String, Integer> percentileMap; 

另請注意,成員變量名稱應與JSON示例匹配RTY名稱完全

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

感謝Origineil的幫助。是的,它現在工作正常。有沒有辦法,如果可能,我可以擁有自己的變量名稱並將JSON屬性名稱映射到這些名稱? – john

+0

我只用過[自定義反序列化器](http://google-gson.googlecode.com/svn/tags/gson-1.7.1/docs/javadocs/com/google/gson/JsonDeserializer.html)或者默認情況下,所以我不像「中間」那樣精通。我不得不研究一下。如果你提供了一個自定義的解串器,你所要求的肯定是可能的。一對夫婦([這裏](http://stackoverflow.com/questions/19169754/parsing-nested-json-data-using-gson/19173302#19173302)和[這裏](http://stackoverflow.com/questions/ 19164515/gson-parsing-unspecified-type-variable/19167552#19167552))我的帖子的例子使用一個。 – Origineil

相關問題