Json解析之Gson庫
Json(JavaScript Object Notation)是一種輕量級的資料交換格式,類似XML,但比XML更小更快更容易解析。當前各種流行的web應用框架都對Json提供良好的支援,各種流行開發語言也支援Json解析。
Java中解析Json的方式也很多,根據官方的JSONObject庫,自己設計的一個抽象工具類:
- import java.io.Serializable;
- import java.util.List;
- import org.json.JSONException;
- import org.json.JSONObject;
- public abstract class JsonParser <T extends Serializable>{
- abstract List<T> getListFromJson(String str);
- abstract T getObjectFromJson(JSONObject jobj);
- public T getObjectFromJson(String str) {
- try {
- JSONObject jsonObject = new JSONObject(str);
- return getObjectFromJson(jsonObject);
- } catch (JSONException e) {
- e.printStackTrace();
- } catch(Exception e){
- e.printStackTrace();
- }
- return null;
- }
- protected String getValueByName(JSONObject jobj, String name)
- throws JSONException{
- if(jobj.has(name)){
- return jobj.getString(name);
- }
- return null;
- }
- }
具體實現的子類如下:
- public class UserInfoParser extends JsonParser<UserInfo> {
- private UserInfoParser() {
- }
- @Override
- List<UserInfo> getListFromJson(String str) {
- try {
- JSONArray array = new JSONArray(str);
- int len = array.length();
- ArrayList<UserInfo> list = new ArrayList<UserInfo>(len);
- for(int i=0;i<len;i++) {
- UserInfo info = getObjectFromJson(array.getJSONObject(i));
- list.add(info);
- }
- return list;
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return null;
- }
- @Override
- UserInfo getObjectFromJson(JSONObject jobj) {
- try {
- UserInfo info = new UserInfo();
- info.setId(getValueByName(jobj, UserInfo.NODE_ID));
- info.setFace(getValueByName(jobj,UserInfo.NODE_FACE));
- info.setUsername(getValueByName(jobj,UserInfo.NODE_USER_NAME));
- return info;
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
當泛型值物件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能有效分離這些不規範的命名到其他模組程式碼中去。
- public class UserInfo implements Serializable {
- private static final long serialVersionUID = 1050128890144400614L;
- private String id;
- private String username;
- private String face;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getFace() {
- return face;
- }
- public void setFace(String face) {
- this.face = face;
- }
- }
2、奉上一個基於Gson的Json解析封裝工具:
- /**
- * Gson類庫的封裝工具類,專門負責解析json資料</br>
- * 內部實現了Gson物件的單例
- * @author zhiweiofli
- * @version 1.0
- * @since 2012-9-18
- */
- public class JsonUtil {
- private static Gson gson = null;
- static {
- if (gson == null) {
- gson = new Gson();
- }
- }
- private JsonUtil() {
- }
- /**
- * 將物件轉換成json格式
- *
- * @param ts
- * @return
- */
- public static String objectToJson(Object ts) {
- String jsonStr = null;
- if (gson != null) {
- jsonStr = gson.toJson(ts);
- }
- return jsonStr;
- }
- /**
- * 將物件轉換成json格式(並自定義日期格式)
- *
- * @param ts
- * @return
- */
- public static String objectToJsonDateSerializer(Object ts,
- final String dateformat) {
- String jsonStr = null;
- gson = new GsonBuilder()
- .registerTypeHierarchyAdapter(Date.class,
- new JsonSerializer<Date>() {
- public JsonElement serialize(Date src,
- Type typeOfSrc,
- JsonSerializationContext context) {
- SimpleDateFormat format = new SimpleDateFormat(
- dateformat);
- return new JsonPrimitive(format.format(src));
- }
- }).setDateFormat(dateformat).create();
- if (gson != null) {
- jsonStr = gson.toJson(ts);
- }
- return jsonStr;
- }
- /**
- * 將json格式轉換成list物件
- *
- * @param jsonStr
- * @return
- */
- public static List<?> jsonToList(String jsonStr) {
- List<?> objList = null;
- if (gson != null) {
- java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<List<?>>() {
- }.getType();
- objList = gson.fromJson(jsonStr, type);
- }
- return objList;
- }
- /**
- * 將json格式轉換成list物件,並準確指定型別
- * @param jsonStr
- * @param type
- * @return
- */
- public static List<?> jsonToList(String jsonStr, java.lang.reflect.Type type) {
- List<?> objList = null;
- if (gson != null) {
- objList = gson.fromJson(jsonStr, type);
- }
- return objList;
- }
- /**
- * 將json格式轉換成map物件
- *
- * @param jsonStr
- * @return
- */
- public static Map<?, ?> jsonToMap(String jsonStr) {
- Map<?, ?> objMap = null;
- if (gson != null) {
- java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<Map<?, ?>>() {
- }.getType();
- objMap = gson.fromJson(jsonStr, type);
- }
- return objMap;
- }
- /**
- * 將json轉換成bean物件
- *
- * @param jsonStr
- * @return
- */
- public static Object jsonToBean(String jsonStr, Class<?> cl) {
- Object obj = null;
- if (gson != null) {
- obj = gson.fromJson(jsonStr, cl);
- }
- return obj;
- }
- /**
- * 將json轉換成bean物件
- *
- * @param jsonStr
- * @param cl
- * @return
- */
- @SuppressWarnings("unchecked")
- public static <T> T jsonToBeanDateSerializer(String jsonStr, Class<T> cl,
- final String pattern) {
- Object obj = null;
- gson = new GsonBuilder()
- .registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
- public Date deserialize(JsonElement json, Type typeOfT,
- JsonDeserializationContext context)
- throws JsonParseException {
- SimpleDateFormat format = new SimpleDateFormat(pattern);
- String dateStr = json.getAsString();
- try {
- return format.parse(dateStr);
- } catch (ParseException e) {
- e.printStackTrace();
- }
- return null;
- }
- }).setDateFormat(pattern).create();
- if (gson != null) {
- obj = gson.fromJson(jsonStr, cl);
- }
- return (T) obj;
- }
- /**
- * 根據
- *
- * @param jsonStr
- * @param key
- * @return
- */
- public static Object getJsonValue(String jsonStr, String key) {
- Object rulsObj = null;
- Map<?, ?> rulsMap = jsonToMap(jsonStr);
- if (rulsMap != null && rulsMap.size() > 0) {
- rulsObj = rulsMap.get(key);
- }
- return rulsObj;
- }
- }
引用方式十分簡單:
- (UserInfo)JsonUtil.jsonToBean(jsonString, UserInfo.class);
3、解析複雜Json的方式
Gson支援解析多層結構的Json,當然對於多層解析的效率,暫時還沒測試過,估計效率下降不會超過JSONObject...
想解析Json中的Json,Json中的Json陣列,Gson提供InstanceCreator結構,來例項化對應的物件,用來載入已解析的json資料。估計解析的流程是,Gson反射屬性名稱前,先考量能否獲得其對應的例項,再對屬性物件進行反射、賦值,如此迭代進行...
例如,解析Json陣列的方式,實現:
- public class UserInfoResult extends ResponseState implements InstanceCreator<List<UserInfo>>{
- private static final long serialVersionUID = -8701527648781449574L;
- public List<UserInfo> userlist;
- @Override
- public List<UserInfo> createInstance(Type arg0) {
- return new ArrayList<UserInfo>(2);
- }
- }
對比JSONObject,Gson的好處在於:
1、高效,安全的反射,帶來高效的解析速度
2、簡化的開發流程,對比JSONObject每次都要設計解析的物件,Gson只需要設計值物件,由此帶來的就是敏捷的開發
3、良好的支援,Gson屬於開源專案,專案位於http://code.google.com/p/google-gson/,現在版本還在不斷升級中,建議使用最新的穩定版。
最後,本文只對比介紹了Gson對Json解析的方面,對於Json的自動化生成,註釋的使用,容以後再分享...
相關文章
- JSON解析器之Gson、FastJson、JacksonJSONAST
- android使用Gson來解析jsonAndroidJSON
- Eclipse安裝GSON,使用GSON轉換Java Object到JSONEclipseJavaObjectJSON
- Android:用GSON 五招之內搞定任何JSON陣列AndroidJSON陣列
- Flutter開發之JSON解析FlutterJSON
- 推薦一個Json解析庫JSON
- 使用Javascript 開發個JSON解析庫JavaScriptJSON
- Json和Map互轉,三個包(org.json/net.sf.json/com.google.gson)JSONGo
- 使用cJSON庫對JSON格式進行解析JSON
- Gson原始碼解析和它的設計模式原始碼設計模式
- 新一代Json解析庫Moshi使用及原理解析JSON
- 一個非常棒的Go-Json解析庫GoJSON
- Jackson 解析json資料之忽略解析欄位註解@JsonIgnorePropertiesJSON
- Exercise:JSON解析JSON
- cJSON:解析JSONJSON
- js json解析JSON
- 推薦一個JSON解析庫,效能還不錯JSON
- C/C++ Qt 運用JSON解析庫 [基礎篇]C++QTJSON
- Golang 流式解析 JsonGolangJSON
- 用JS解析JSONJSON
- java解析json listJavaJSON
- Swift iOS : 解析jsonSwiftiOSJSON
- json解析模組JSON
- Windows10 VS2017 C++ Json解析(使用jsoncpp庫)WindowsC++JSON
- gson-plugin告別Json資料型別不一致(一)PluginJSON資料型別
- Flutter 中的 JSON 解析FlutterJSON
- oracle json 解析函式OracleJSON函式
- Spark Structured Streaming 解析 JSONSparkStructJSON
- ajax解析json物件集合JSON物件
- 解析大資料json大資料JSON
- linux下json解析神器----jqLinuxJSON
- Python中解析json資料PythonJSON
- 細說 Golang 的 JSON 解析GolangJSON
- Flutter JSON 解析懶人攻略FlutterJSON
- android解析HashMap格式的jsonAndroidHashMapJSON
- Java JSON組成和解析JavaJSON
- 使用JSONPath解析JSON資料JSON
- Flutter 三種JSON解析方式FlutterJSON
- Flutter 解析JSON 三種方式FlutterJSON