首页 > 技术文章 > Gson解析JSON中动态未知字段key的方法

jonzone 2017-02-16 14:44 原文

转载自:Gson解析JSON中动态未知字段key的方法

原帖地址:http://blog.csdn.net/chaosminds/article/details/49049455

     前面一篇文章我介绍了Gson的解析的基本方法。但我们在享受Gson解析的高度封装带来的便利时,有时可能会遇到一些特殊情况,比如json数据中的字段key是动态可变的时候,由于Gson是使用静态注解的方式来设置实体对象的,因此我们很难直接对返回的类型来判断。但Gson在解析过程中如果不知道解析的字段,就会将所有变量存储在一个Map中,我们只要实例化这个map就能动态地取出key和value了。

       先给出一段jsondata,这是天气预报的数据,其中day_20151002这种key是随日期而变化的,在实体类中就不能当做静态变量来处理,我们就通过map来取出其映射对象。

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. "resultcode":"200","reason":"successed!",  
  2.     "result":{  
  3.             "sk":{  
  4.                  "temp":"24","wind_direction":"东北风","wind_strength":"2级","humidity":"28%","time":"17:38"  
  5.                   },  
  6.          "today":{  
  7.                  "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":""  
  8.                  },  
  9.         "future":{  
  10.                  "day_20151011":{"temperature":"15℃~26℃","weather":"多云转晴","wind":"东北风微风","week":"星期日","date":"20151011"},  
  11.                  "day_20151012":{"temperature":"16℃~27℃","weather":"晴转多云","wind":"微风","week":"星期一","date":"20151012"},  
  12.                  "day_20151013":{"temperature":"16℃~26℃","weather":"多云转晴",,"wind":"微风","week":"星期二","date":"20151013"},  
  13.                  "day_20151014":{"temperature":"17℃~27℃","weather":"晴","wind":"北风微风","week":"星期三","date":"20151014"},  
  14.                  "day_20151015":{"temperature":"17℃~28℃","weather":"晴","wind":"北风微风","week":"星期四","date":"20151015"},  
  15.                  "day_20151016":{"temperature":"17℃~30℃","weather":"晴","wind":"北风微风","week":"星期五","date":"20151016"},  
  16.                  "day_20151017":{"temperature":"17℃~30℃","weather":"晴","wind":"北风微风","week":"星期六","date":"20151017"}  
  17.                  }  
  18.               },  
  19.     "error_code":0  
  20. }  

实体类中放上set、get和toString方法就太长了,这里就没有加上去。

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class FutureDay {  
  2.     private String temperature;  
  3.     private String weather;  
  4.     private String wind;  
  5.     private String week;  
  6.     private String date;  
  7. }  
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class Result {  
  2.     private Sk sk;  
  3.     private Today today;  
  4.     private Map<String,FutureDay> future;  
  5. }  
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class Sk {  
  2.     private String temp;  
  3.     private String wind_direction;  
  4.     private String wind_strength;  
  5.     private String humidity;  
  6.     private String time;  
  7. }  
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class Today {  
  2.     private String temperature;  
  3.     private String weather;  
  4.     private String week;  
  5.     private String city;  
  6.     private String date_y;  
  7.     private String dressing_index;  
  8.     private String dressing_advice;  
  9.     private String uv_index;  
  10.     private String comfort_index;  
  11.     private String wash_index;  
  12.     private String travel_index;  
  13.     private String exercise_index;  
  14.     private String drying_index;  
  15. }  
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class Response {  
  2.     private String resultcode;  
  3.     private String reason;  
  4.     private String error_code;  
  5.     private Result result;  
  6. }  
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. import java.io.BufferedReader;  
  2. import java.io.FileReader;  
  3. import java.util.Map;  
  4. import weather.*;  
  5. import com.google.gson.Gson;  
  6.   
  7.   
  8. public class GsonParseDynamicKey {  
  9.     public static  void main( String args []){  
  10.         String jsondata = readJsonFile();//从文件中读取出json字符串,并打印出来  
  11.         Gson gson = new Gson();  
  12.         System.out.println("Start Gson parse jsondata");     
  13.         Response response = gson.fromJson(jsondata, Response.class);          
  14.         System.out.println(response.toString());  
  15.         System.out.println(response.getResult().getSk().toString());  
  16.         System.out.println(response.getResult().getToday().toString());  
  17.   
  18.         Map<String, FutureDay> future = response.getResult().getFuture(); //对动态的key,来创建map,间接从中取出实体类futrue。  
  19.         System.out.println("Keyset method");                     //这里取出value的方法有两种keySet() entrySet().都给出了遍历的方法  
  20.         for (String key:future.keySet()){                        //遍历取出key,再遍历map取出value。  
  21.             System.out.println("key:"+key);   
  22.             System.out.println(future.get(key).toString());  
  23.         }  
  24.   
  25.         System.out.println("Entryset method");  
  26.         for (Map.Entry<String,FutureDay> pair:future.entrySet()){//遍历取出键值对,调用getkey(),getvalue()取出key和value。  
  27.              System.out.println("key:"+pair.getKey());  
  28.              System.out.println(pair.getValue().toString());  
  29.        }      
  30. }  
 

这里顺便一提遍历Map的两种方法keySet(),entrySet()的差别。

keySet()方法返回的是key的集合set,entrySet()返回的是键值对的集合set。虽然两者从set遍历取出元素的方法是一样的,但是根据这个元素取出value的效率有些不同。前者取出的元素是key,还要去原map中遍历取出value。
后者取出的元素是键值对,直接调用getkey(),getvalue()方法就能快速取出key和value。显然在map中存在大量键值对时,使用entrySet()来取出value的效率更高。

推荐阅读