Gson解析Json

Json(JavaScript Object Notation)是一種輕量級的數據交換格式,類似XML,但比XML更小更快更容易解析。當前各種流行的web應用框架都對Json提供良好的支持,各種流行開發語言也支持Json解析。

 

Java中解析Json的方式也很多,根據官方的JSONObject庫,自己設計的一個抽象工具類:

 

Java代碼  收藏代碼

  1. import java.io.Serializable;  

  2. import java.util.List;  

  3.   

  4. import org.json.JSONException;  

  5. import org.json.JSONObject;  

  6.   

  7. public abstract class JsonParser <T extends Serializable>{  

  8.       

  9.     abstract List<T> getListFromJson(String str);  

  10.       

  11.     abstract T getObjectFromJson(JSONObject jobj);  

  12.       

  13.     public T getObjectFromJson(String str) {  

  14.         try {  

  15.             JSONObject jsonObject = new JSONObject(str);  

  16.             return getObjectFromJson(jsonObject);  

  17.         } catch (JSONException e) {  

  18.             e.printStackTrace();   

  19.         } catch(Exception e){  

  20.             e.printStackTrace();  

  21.         }  

  22.         return null;  

  23.     }  

  24.       

  25.     protected String getValueByName(JSONObject jobj, String name)  

  26.             throws JSONException{  

  27.         if(jobj.has(name)){  

  28.             return jobj.getString(name);  

  29.         }  

  30.         return null;  

  31.     }  

  32.       

  33. }  

 

具體實現的子類如下:

 

Java代碼  收藏代碼

  1. public class UserInfoParser extends JsonParser<UserInfo> {  

  2.   

  3.     private UserInfoParser() {  

  4.           

  5.     }  

  6.       

  7.     @Override  

  8.     List<UserInfo> getListFromJson(String str) {  

  9.         try {  

  10.             JSONArray array = new JSONArray(str);  

  11.             int len = array.length();  

  12.             ArrayList<UserInfo> list = new ArrayList<UserInfo>(len);  

  13.             for(int i=0;i<len;i++) {  

  14.                 UserInfo info = getObjectFromJson(array.getJSONObject(i));  

  15.                 list.add(info);  

  16.             }  

  17.             return list;  

  18.         } catch (JSONException e) {  

  19.             e.printStackTrace();  

  20.         }  

  21.         return null;  

  22.     }  

  23.   

  24.     @Override  

  25.     UserInfo getObjectFromJson(JSONObject jobj) {  

  26.         try {  

  27.             UserInfo info = new UserInfo();  

  28.             info.setId(getValueByName(jobj, UserInfo.NODE_ID));  

  29.             info.setFace(getValueByName(jobj,UserInfo.NODE_FACE));  

  30.             info.setUsername(getValueByName(jobj,UserInfo.NODE_USER_NAME));  

  31.             return info;  

  32.         } catch (JSONException e) {  

  33.             e.printStackTrace();  

  34.         }  

  35.         return null;  

  36.     }  

  37.   

  38. }  

 

當泛型值對象T,對應的數據結構比較簡單,層次比較少的時候,官方的JSONObject庫解析還過得去。當遇到層次較多(Json裏面包含N個Json數組),數據結構複雜(Json由對個複雜數據的Json組成)的Json,解析速度就會大大降低!

 

在處理複雜Json結構時,我推薦使用Google的Gson解析庫。剛剛接觸Gson時,我有以下疑慮:

1、Gson對Json的支持度如何,能不能支持所有的Json結構?

2、由於Gson是基於Java的反射原理來實現的,解析的效率如何保證?

3、上手難度如何?

 

當我在項目實驗性地引入Gson後,我o嘴了~~真不愧是Google出品,實屬佳品!

 

再我的項目是基於android平臺的App,使用Gson之前,不僅http請求和Json數據解析的耗時太長,而且內存佔有一直居高不下。

使用Gson後,解析的時間縮短了30%(這只是Json的解析時間,不算上http請求的時間),內存佔用足足減少了一半!!!最重要的是,開發效率還提高不少,何以見得,請看:

 

1、值對象必須實現序列化接口,成員屬性的名稱必須與Json數據的key一致,建議遵從J2EE的標準,使用get-set方法控制屬性的訪問,因爲Json的key是後臺應用定義的,假如後臺與前臺的開發語言不同,命名規範也不一致,使用get-set能有效分離這些不規範的命名到其他模塊代碼中去。

 

 

Java代碼  收藏代碼

  1. public class UserInfo implements Serializable {  

  2.   

  3.     private static final long serialVersionUID = 1050128890144400614L;  

  4.   

  5.     private String id;  

  6.     private String username;  

  7.     private String face;  

  8.   

  9.     public String getId() {  

  10.         return id;  

  11.     }  

  12.   

  13.     public void setId(String id) {  

  14.         this.id = id;  

  15.     }  

  16.   

  17.     public String getUsername() {  

  18.         return username;  

  19.     }  

  20.   

  21.     public void setUsername(String username) {  

  22.         this.username = username;  

  23.     }  

  24.   

  25.     public String getFace() {  

  26.         return face;  

  27.     }  

  28.   

  29.     public void setFace(String face) {  

  30.         this.face = face;  

  31.     }  

  32.   

  33. }  

 

 

2、奉上一個基於Gson的Json解析封裝工具:

 

Java代碼  收藏代碼

  1. /** 

  2.  * Gson類庫的封裝工具類,專門負責解析json數據</br> 

  3.  * 內部實現了Gson對象的單例 

  4.  * @author zhiweiofli 

  5.  * @version 1.0 

  6.  * @since 2012-9-18 

  7.  */  

  8. public class JsonUtil {  

  9.   

  10.     private static Gson gson = null;  

  11.       

  12.     static {  

  13.         if (gson == null) {  

  14.             gson = new Gson();  

  15.         }  

  16.     }  

  17.   

  18.     private JsonUtil() {  

  19.       

  20.     }  

  21.   

  22.     /** 

  23.      * 將對象轉換成json格式 

  24.      *  

  25.      * @param ts 

  26.      * @return 

  27.      */  

  28.     public static String objectToJson(Object ts) {  

  29.         String jsonStr = null;  

  30.         if (gson != null) {  

  31.             jsonStr = gson.toJson(ts);  

  32.         }  

  33.         return jsonStr;  

  34.     }  

  35.   

  36.     /** 

  37.      * 將對象轉換成json格式(並自定義日期格式) 

  38.      *  

  39.      * @param ts 

  40.      * @return 

  41.      */  

  42.     public static String objectToJsonDateSerializer(Object ts,  

  43.             final String dateformat) {  

  44.         String jsonStr = null;  

  45.         gson = new GsonBuilder()  

  46.                 .registerTypeHierarchyAdapter(Date.class,  

  47.                         new JsonSerializer<Date>() {  

  48.                             public JsonElement serialize(Date src,  

  49.                                     Type typeOfSrc,  

  50.                                     JsonSerializationContext context) {  

  51.                                 SimpleDateFormat format = new SimpleDateFormat(  

  52.                                         dateformat);  

  53.                                 return new JsonPrimitive(format.format(src));  

  54.                             }  

  55.                         }).setDateFormat(dateformat).create();  

  56.         if (gson != null) {  

  57.             jsonStr = gson.toJson(ts);  

  58.         }  

  59.         return jsonStr;  

  60.     }  

  61.   

  62.     /** 

  63.      * 將json格式轉換成list對象 

  64.      *  

  65.      * @param jsonStr 

  66.      * @return 

  67.      */  

  68.     public static List<?> jsonToList(String jsonStr) {  

  69.         List<?> objList = null;  

  70.         if (gson != null) {  

  71.             java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<List<?>>() {  

  72.             }.getType();  

  73.             objList = gson.fromJson(jsonStr, type);  

  74.         }  

  75.         return objList;  

  76.     }  

  77.       

  78.     /** 

  79.      * 將json格式轉換成list對象,並準確指定類型 

  80.      * @param jsonStr 

  81.      * @param type 

  82.      * @return 

  83.      */  

  84.     public static List<?> jsonToList(String jsonStr, java.lang.reflect.Type type) {  

  85.         List<?> objList = null;  

  86.         if (gson != null) {  

  87.             objList = gson.fromJson(jsonStr, type);  

  88.         }  

  89.         return objList;  

  90.     }  

  91.   

  92.     /** 

  93.      * 將json格式轉換成map對象 

  94.      *  

  95.      * @param jsonStr 

  96.      * @return 

  97.      */  

  98.     public static Map<?, ?> jsonToMap(String jsonStr) {  

  99.         Map<?, ?> objMap = null;  

  100.         if (gson != null) {  

  101.             java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<Map<?, ?>>() {  

  102.             }.getType();  

  103.             objMap = gson.fromJson(jsonStr, type);  

  104.         }  

  105.         return objMap;  

  106.     }  

  107.   

  108.     /** 

  109.      * 將json轉換成bean對象 

  110.      *  

  111.      * @param jsonStr 

  112.      * @return 

  113.      */  

  114.     public static Object jsonToBean(String jsonStr, Class<?> cl) {  

  115.         Object obj = null;  

  116.         if (gson != null) {  

  117.             obj = gson.fromJson(jsonStr, cl);  

  118.         }  

  119.         return obj;  

  120.     }  

  121.   

  122.     /** 

  123.      * 將json轉換成bean對象 

  124.      *  

  125.      * @param jsonStr 

  126.      * @param cl 

  127.      * @return 

  128.      */  

  129.     @SuppressWarnings("unchecked")  

  130.     public static <T> T jsonToBeanDateSerializer(String jsonStr, Class<T> cl,  

  131.             final String pattern) {  

  132.         Object obj = null;  

  133.         gson = new GsonBuilder()  

  134.                 .registerTypeAdapter(Date.classnew JsonDeserializer<Date>() {  

  135.                     public Date deserialize(JsonElement json, Type typeOfT,  

  136.                             JsonDeserializationContext context)  

  137.                             throws JsonParseException {  

  138.                         SimpleDateFormat format = new SimpleDateFormat(pattern);  

  139.                         String dateStr = json.getAsString();  

  140.                         try {  

  141.                             return format.parse(dateStr);  

  142.                         } catch (ParseException e) {  

  143.                             e.printStackTrace();  

  144.                         }  

  145.                         return null;  

  146.                     }  

  147.                 }).setDateFormat(pattern).create();  

  148.         if (gson != null) {  

  149.             obj = gson.fromJson(jsonStr, cl);  

  150.         }  

  151.         return (T) obj;  

  152.     }  

  153.   

  154.     /** 

  155.      * 根據 

  156.      *  

  157.      * @param jsonStr 

  158.      * @param key 

  159.      * @return 

  160.      */  

  161.     public static Object getJsonValue(String jsonStr, String key) {  

  162.         Object rulsObj = null;  

  163.         Map<?, ?> rulsMap = jsonToMap(jsonStr);  

  164.         if (rulsMap != null && rulsMap.size() > 0) {  

  165.             rulsObj = rulsMap.get(key);  

  166.         }  

  167.         return rulsObj;  

  168.     }  

  169.   

  170. }  

 

引用方式十分簡單:

 

Java代碼  收藏代碼

  1. (UserInfo)JsonUtil.jsonToBean(jsonString, UserInfo.class);  

 

3、解析複雜Json的方式

Gson支持解析多層結構的Json,當然對於多層解析的效率,暫時還沒測試過,估計效率下降不會超過JSONObject...

想解析Json中的Json,Json中的Json數組,Gson提供InstanceCreator結構,來實例化對應的對象,用來加載已解析的json數據。估計解析的流程是,Gson反射屬性名稱前,先考量能否獲得其對應的實例,再對屬性對象進行反射、賦值,如此迭代進行...

 

例如,解析Json數組的方式,實現:

 

Java代碼  收藏代碼

  1. public class UserInfoResult extends ResponseState implements InstanceCreator<List<UserInfo>>{  

  2.   

  3.     private static final long serialVersionUID = -8701527648781449574L;  

  4.       

  5.     public List<UserInfo> userlist;  

  6.   

  7.     @Override  

  8.     public List<UserInfo> createInstance(Type arg0) {  

  9.         return new ArrayList<UserInfo>(2);  

  10.     }  

  11. }  

 

對比JSONObject,Gson的好處在於:

1、高效,安全的反射,帶來高效的解析速度

2、簡化的開發流程,對比JSONObject每次都要設計解析的對象,Gson只需要設計值對象,由此帶來的就是敏捷的開發

3、良好的支持,Gson屬於開源項目,項目位於http://code.google.com/p/google-gson/,現在版本還在不斷升級中,建議使用最新的穩定版。

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章