1. 程式人生 > >Gson解析JSON中動態未知欄位key的方法

Gson解析JSON中動態未知欄位key的方法

       前面一篇文章我介紹了Gson的解析的基本方法。但我們在享受Gson解析的高度封裝帶來的便利時,有時可能會遇到一些特殊情況,比如json資料中的欄位key是動態可變的時候,由於Gson是使用靜態註解的方式來設定實體物件的,因此我們很難直接對返回的型別來判斷。但Gson在解析過程中如果不知道解析的欄位,就會將所有變數儲存在一個Map中,我們只要例項化這個map就能動態地取出key和value了。

       先給出一段jsondata,這是天氣預報的資料,其中day_20151002這種key是隨日期而變化的,在實體類中就不能當做靜態變數來處理,我們就通過map來取出其對映物件。

{ "resultcode":"200","reason":"successed!",
    "result":{
            "sk":{
                 "temp":"24","wind_direction":"東北風","wind_strength":"2級","humidity":"28%","time":"17:38"
                  },
         "today":{
                 "temperature":"15℃~26℃","weather":"多雲轉晴","wind":"東北風微風","week":"星期日","city":"桂林","date_y":"2015年10月11日","dressing_index":"舒適","dressing_advice":"建議著長袖T恤、襯衫加單褲等服裝。年老體弱者宜著針織長袖襯衫、馬甲和長褲。","uv_index":"弱","comfort_index":"","wash_index":"較適宜","travel_index":"較適宜","exercise_index":"較適宜","drying_index":""
                 },
        "future":{
                 "day_20151011":{"temperature":"15℃~26℃","weather":"多雲轉晴","wind":"東北風微風","week":"星期日","date":"20151011"},
                 "day_20151012":{"temperature":"16℃~27℃","weather":"晴轉多雲","wind":"微風","week":"星期一","date":"20151012"},
                 "day_20151013":{"temperature":"16℃~26℃","weather":"多雲轉晴",,"wind":"微風","week":"星期二","date":"20151013"},
                 "day_20151014":{"temperature":"17℃~27℃","weather":"晴","wind":"北風微風","week":"星期三","date":"20151014"},
                 "day_20151015":{"temperature":"17℃~28℃","weather":"晴","wind":"北風微風","week":"星期四","date":"20151015"},
                 "day_20151016":{"temperature":"17℃~30℃","weather":"晴","wind":"北風微風","week":"星期五","date":"20151016"},
                 "day_20151017":{"temperature":"17℃~30℃","weather":"晴","wind":"北風微風","week":"星期六","date":"20151017"}
                 }
              },
    "error_code":0
}

實體類中放上set、get和toString方法就太長了,這裡就沒有加上去。

public class FutureDay {
    private String temperature;
    private String weather;
    private String wind;
    private String week;
    private String date;
}
public class Result {
    private Sk sk;
    private Today today;
    private Map<String,FutureDay> future;
}

public class Sk {
    private String temp;
    private String wind_direction;
    private String wind_strength;
    private String humidity;
    private String time;
}

public class Today {
    private String temperature;
    private String weather;
    private String week;
    private String city;
    private String date_y;
    private String dressing_index;
    private String dressing_advice;
    private String uv_index;
    private String comfort_index;
    private String wash_index;
    private String travel_index;
    private String exercise_index;
    private String drying_index;
}

public class Response {
    private String resultcode;
    private String reason;
    private String error_code;
    private Result result;
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Map;
import weather.*;
import com.google.gson.Gson;


public class GsonParseDynamicKey {
    public static  void main( String args []){
        String jsondata = readJsonFile();//從檔案中讀取出json字串,並打印出來
        Gson gson = new Gson();
        System.out.println("Start Gson parse jsondata");   
        Response response = gson.fromJson(jsondata, Response.class);        
        System.out.println(response.toString());
        System.out.println(response.getResult().getSk().toString());
        System.out.println(response.getResult().getToday().toString());

        Map<String, FutureDay> future = response.getResult().getFuture(); //對動態的key,來建立map,間接從中取出實體類futrue。
        System.out.println("Keyset method");                     //這裡取出value的方法有兩種keySet() entrySet().都給出了遍歷的方法
        for (String key:future.keySet()){                        //遍歷取出key,再遍歷map取出value。
            System.out.println("key:"+key); 
            System.out.println(future.get(key).toString());
        }

        System.out.println("Entryset method");
        for (Map.Entry<String,FutureDay> pair:future.entrySet()){//遍歷取出鍵值對,呼叫getkey(),getvalue()取出key和value。
             System.out.println("key:"+pair.getKey());
             System.out.println(pair.getValue().toString());
       }    
}

這裡順便一提遍歷Map的兩種方法keySet(),entrySet()的差別。

keySet()方法返回的是key的集合set,entrySet()返回的是鍵值對的集合set。雖然兩者從set遍歷取出元素的方法是一樣的,但是根據這個元素取出value的效率有些不同。前者取出的元素是key,還要去原map中遍歷取出value。
後者取出的元素是鍵值對,直接呼叫getkey(),getvalue()方法就能快速取出key和value。顯然在map中存在大量鍵值對時,使用entrySet()來取出value的效率更高。

下面是最後打印出來的結果。

工程原始碼的下載地址點選開啟連結