JSON數據解析

    JSON是一種輕量級的數據交換格式,它的全稱為JavaScript Object Notation,輕量級的數據交換格式,主要用于跟服務器進行交換數據。我所做的項目來看,當下的服務器與客戶端數據交換幾乎都是用JSON了,所以作為移動開發者的我們務必要吃透JSON解析。

JSON的特點:

1、JSON比XML的數據傳遞的有效性高;
2、JSON完全獨立于編程語言;
3、JSON的本質是具有特定格式的字符串;
4、易于人閱讀和編寫,同時也易于機器解析和生成。

JSON數據格式(JSON對象、JSON數組):

1、JSON對象:{ }

結構:{key1:value1,key2:value2,key3:value3}
key的數據類型:字符串
value的數據類型:字符串、數值、null、JSON對象、JSON數組
例子:

{  " name " : " luoweichao ", " blogUrl " : " luoweichao.top "  } 

//以key/value鍵值對形式構建的,正確

{  " name " : " luoweichao ", " luoweichao.top "  }

//沒有以key/value鍵值對形式構建的,錯誤
2、JSON數組:[ ]

結構:[value1,value2,value3]
value的數據類型:字符串、數值、null、JSON對象、JSON數組
例子:

[ " 1 " , " csdn " , {  " name " : " luoweichao ", " blogUrl " : " luoweichao.top "  }  ] 

//正確

[ " 1 " , " name " : " luoweichao "  ]  //錯誤

JSON解析方向:
1、將Java對象(包括集合)轉換成JSON格式字符串;(服務端)
2、將JSON格式字符串轉換成Java對象(包括集合)。(客戶端)
3、JSON和Java之間的轉換關系:JSON中的對象對應著Java中的對象;JSON中的數組對應這Java中的集合。
Android原生技術解析JSON:特點:很麻煩,對于復雜的json數據解析很容易出錯!(不推薦使用)
1、解析JSON對象的API:JsonObjectJSONObject(String json);將Json字符串解析成Json對象;XxxgetXxx(String name) ;根據name在json對象中得到相應的value。示例代碼:(1)獲取或創建JSON數據(為了方便,這里就直接創建了):
[java] view plain copy
String json = "{\n" +"\t"id":2, "name":"金魚", \n" +"\t"price":12.3, \n" +"\t"imagePath":"http://blog.csdn.net/qq_29269233/L05_Server/images/f1.jpg"\n" +"}\n";
ShopInfo shopInfo = null;

(2)解析Json對象:
[java] view plain copy

try {JSONObject jsonObject = new JSONObject(json);// int id = jsonObject.getInt("id");int id1 = jsonObject.optInt("id");
String name = jsonObject.optString("name"); double price = jsonObject.optDouble("price"); String imagePath = jsonObject.optString("imagePath"); // 封裝Java對象  shopInfo = new ShopInfo(id1, name, price, imagePath); } catch (JSONException e) { e.printStackTrace(); }

注意:這里記得要加try_catch異常處理。(3)創建JavaBean類,并顯示解析后的數據:
[java] view plain copy
tv_native_last.setText(shopInfo.toString());
2、解析Json數組的API:JSONArrayJSONArray(String json);將json字符串解析成json數組;int length();得到json數組中元素的個數;XxxgetXxx(int s) ;根據下標得到json數組中對應的元素數據。示例代碼:(1)獲取或創建JSON數據:
[java] view plain copy
String json = "[\n" +" {\n" +" "id": 1,\n" +" "imagePath": "http://blog.csdn.net/qq_29269233/f1.jpg",\n" +" "name": "金魚1",\n" +" "price": 12.3\n" +" },\n" +" {\n" +" "id": 2,\n" +" "imagePath": "http://blog.csdn.net/qq_29269233/f2.jpg",\n" +" "name": "金魚2",\n" +" "price": 12.5\n" +" }\n" +"]";
(2)解析json數組:
[java] view plain copy

try {JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {  JSONObject jsonObject = jsonArray.getJSONObject(i);  if (jsonObject != null) { int id = jsonObject.optInt("id");  String name = jsonObject.optString("name");  double price = jsonObject.optDouble("price");  String imagePath = jsonObject.optString("imagePath");  // 封裝Java對象 ShopInfo shopInfo = new ShopInfo(id, name, price, imagePath);  shops.add(shopInfo);  } } } catch (JSONException e) { e.printStackTrace();  }

(3)顯示解析后的數據:
[java] view plain copy
tv_native_last.setText(shops.toString());
到此為止,這就是用原生的技術去解析json了,至于復雜特殊的json數據怎樣去解析,也是大同小異了,一層一層解析就對了!
用Gson框架技術解析JSON:特點:解析沒那么麻煩,代碼量簡潔,可以很方便地解析復雜的Json數據,而且谷歌官方也推薦使用。先放出jar包的下載地址:https://mvnrepository.com/artifact/com.google.code.gson/gson


如過用Android Studio做開發的話,可以通過Gradle,直接添加依賴,不用下載jar包,很方便,如下:

1、用Gson解析JSON對象:(1)將gson的jar包導入到項目libs目錄下,或者直接通過Gradle添加依賴:
[java] view plain copy
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0'
(2)創建Gson對象:[java] view plain copy
Gson gson = new Gson();
(3)通過創建的Gson對象調用fromJson()方法,返回該json數據對象的Java對象;
[java] view plain copy
ShopInfo shopInfo = gson.fromJson(json, ShopInfo.class);
注意要記得創建對象的JavaBean類;要求json對象中的key的名稱與Java對象的JavaBean類中的屬性名要相同,否則解析不成功!示例代碼如下:[java] view plain copy
// 1 獲取或創建JSON數據String json = "{\n" +"\t"id":2, "name":"金魚", \n" +"\t"price":12.3, \n" +"\t"imagePath":"http://blog.csdn.net/qq_29269233/L05_Server/images/f1.jpg"\n" +"}\n";
// 2 解析JSON數據 Gson gson = new Gson(); ShopInfo shopInfo = gson.fromJson(json, ShopInfo.class); // 3 展示數據 tv_gson_last.setText(shopInfo.toString());

2、用Gson解析JSON數組:(1)(2)與上面相同,要用Gson就要先添加依賴,然后創建Gson對象;(3)通過創建的Gson對象調用fromJson()方法,返回該json數據對應的Java集合。這里但強調一下:要記得創建對象的JavaBean類;要求json對象中的key的名稱與Java對象的JavaBean類中的屬性名要相同,否則解析不成功!
示例代碼如下:
[java] view plain copy
// 1 獲取或創建JSON數據String json = "[\n" +" {\n" +" "id": 1,\n" +" "imagePath": "http://blog.csdn.net/qq_29269233/f1.jpg",\n" +" "name": "金魚1",\n" +" "price": 12.3\n" +" },\n" +" {\n" +" "id": 2,\n" +" "imagePath": "http://blog.csdn.net/qq_29269233/f2.jpg",\n" +" "name": "金魚2",\n" +" "price": 12.5\n" +" }\n" +"]";
// 2 解析JSON數據 Gson gson = new Gson(); List<ShopInfo> shops = gson.fromJson(json, new TypeToken<List<ShopInfo>>() { }.getType()); // 3 展示數據 tv_gson_last.setText(shops.toString());

還是那句話,復雜特殊的都是大同小異,理解了方法就沒問題了!3、Gson還可以將Java對象、Java對象的List 轉換為json字符串{};有興趣的就去研究一下哈。
用Fastjson框架技術解析JSON:特點:Fastjson是用Java語言編寫的高性能功能完善的JSON庫。它采用了一種“假定有序、快速匹配”的算法,把JSON Parse的性能提升到極致,是目前Java語言中最快的JSON庫。Fastjson是阿里巴巴開源框架,已經開源到github上了,地址為:https://github.com/alibaba/fastjson



在github上,我還專門留意了這個,哈哈,gson和fastjson比起來,gson就是“烏龜”

要使用Fastjson,也是想Gson一樣,先導入jar包,或者在Gradle中添加依賴:
[java] view plain copy
compile 'com.alibaba:fastjson:1.1.55.android'
添加好依賴后就可以使用Fastjson了!1、用Fastjson解析JSON對象:利用Fastjson的JSON調用parseObject()方法,獲取轉換后的Java對象。注意要記得創建對象的JavaBean類;要求json對象中的key的名稱與Java對象的JavaBean類中的屬性名要相同,否則解析不成功!示例代碼:
[java] view plain copy
// 1 獲取或創建json數據String json = "{\n" +"\t"id":2, "name":"金魚", \n" +"\t"price":12.3, \n" +"\t"imagePath":"http://blog.csdn.net/qq_29269233/L05_Server/images/f1.jpg"\n" +"}\n";
// 2 解析JSON數據 ShopInfo shopInfo = JSON.parseObject(json, ShopInfo.class); // 3 顯示數據 tv_fastjson_last.setText(shopInfo.toString());

2.用Fastjson解析JSON數組:利用Fastjson的JSON調用parseArray()方法,獲取轉換后的Java集合。這里但強調一下:要記得創建對象的JavaBean類;要求json對象中的key的名稱與Java對象的JavaBean類中的屬性名要相同,否則解析不成功!示例代碼:
[java] view plain copy
// 1 獲取或創建json數據String json = "[\n" +" {\n" +" "id": 1,\n" +" "imagePath": "http://blog.csdn.net/qq_29269233/f1.jpg",\n" +" "name": "金魚1",\n" +" "price": 12.3\n" +" },\n" +" {\n" +" "id": 2,\n" +" "imagePath": "http://blog.csdn.net/qq_29269233/f2.jpg",\n" +" "name": "金魚2",\n" +" "price": 12.5\n" +" }\n" +"]";
// 2 解析JSON數據 List<ShopInfo> shopInfos = JSON.parseArray(json, ShopInfo.class); // 3 顯示數據 tv_fastjson_last.setText(shopInfos.toString());

3、同樣Fastjson也可以將Java對象、Java對象的List 轉換為json字符串{};有興趣的就去研究一下哈。到此為止,算是比較詳細地介紹了json解析了。

前言:

最近為了統一項目中使用的框架,發現項目中用到了兩種json解析框架,他們就是當今非常主流的json解析框架:google的Gson 和阿里巴巴的FastJson,為了廢除其中一個所以來個性能和使用的大比拼。

FastJson簡介:Fastjson是一個Java語言編寫的JSON處理器,由阿里巴巴公司開發。

當前版本: fastjson-1.2.14.jar

下載地址http://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.14/

對象轉化成json:

/**
 * 對象轉化為json fastjson 使用方式
 *
 * @return
 */
public static String objectToJsonForFastJson(Object object) {
    if (object == null) {
        return "";
    }
    try {
        return JSON.toJSONString(object);
    } catch (JSONException e) {
    } catch (Exception e) {
    }
    return "";
}

json轉化成對象:

/**
* json轉化為對象 fastjson 使用方式
*
* @return
*/
public static <T> T jsonToObjectForFastJson(String jsonData, Class<T> clazz) {
if (TextUtils.isEmpty(jsonData)) {
return null;
}
try {
return parseObject(jsonData, clazz);
} catch (Exception e) {
}
return null;
}
json轉化成List:

/**
*json轉化為List fastjson 使用方式
*/
public static List jsonToListForFastJson(String jsonData) {
if (TextUtils.isEmpty(jsonData)) {
return null;
}
List arrayList = null;
try {
arrayList = parseObject(jsonData,new TypeReference<ArrayList>(){});
} catch (Exception e) {
}
return arrayList;

}

json轉化這Map:

/**
 *json轉化為Map  fastjson 使用方式
 */
public static Map jsonToMapForFastJson(String jsonData){
    if (TextUtils.isEmpty(jsonData)) {
        return null;
    }
    Map map = null;
    try{
        map =  parseObject(jsonData,new TypeReference<Map>(){});
    }catch (Exception e){
        e.printStackTrace();
    }
    return map;
}

Gson 簡介:Gson由谷歌研發,可以把Java對象轉換成JSON,也可以把JSON字符串轉換成一個相等的Java對象。Gson支持任意復雜Java對象包括沒有源代碼的對象。

當前版本2.40

使用方式 build.gradle 中配置 compile 'com.google.code.gson:gson:2.4'

對象轉化json:

/**
* 對象轉化為json對象 Gson 使用方式
*
* @return
*/
public static String objectToJsonForGson(Object object) {
if (object == null) {
return "";
}
Gson gson;
try {
gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
return gson.toJson(object);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
json轉化成對象:

/**
* json轉化為對象 Gson 使用方式
*
* @return
*/

public static <T> T jsonToObjectForGson(String jsonData, Class<T> clazz) {
    if (TextUtils.isEmpty(jsonData)) {
        return null;
    }
    T finalResult = null;
    try {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        finalResult = gson.fromJson(jsonData, clazz);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return finalResult;
}

json轉化成List:

/**
*json轉化為集合 Gson 使用方式
*/
public static List jsonToListForForGson(String jsonData) {
if (TextUtils.isEmpty(jsonData)) {
return null;
}
List list = null;
try {
Type listType = new TypeToken<ArrayList>() {
}.getType();
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
list = gson.fromJson(jsonData, listType);
} catch (Exception e) {
}
return list;
}
json轉化為Map:

/**
*json轉化為Map fastjson 使用方式
*/
public static Map jsonToMapForForGson(String jsonData){
if (TextUtils.isEmpty(jsonData)) {
return null;
}
Map map = null;
try {
Type listType = new TypeToken<Map>() {
}.getType();
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
map = gson.fromJson(jsonData, listType);
} catch (Exception e) {
}
return map;
}
測試性能程序:

第一步:首先創建一個實體對象Person

public class Person {

private String name;//姓名
private int age;//年齡

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}
第二部:創建一個測試集合:

  List<Person> personList=new ArrayList<>();
    int testMaxCount=1000;//測試的最大數據條數 
    //添加測試數據
    for(int i=0;i<testMaxCount;i++){
        Person person =new Person();
        person.setAge(i);
        person.setName(String.valueOf(i));
        personList.add(person);
    }

分別執行兩者的轉化和解析代碼:

    //FastJson生成json數據
    long start=System.currentTimeMillis();
    String jsonData=JsonUtils.objectToJsonForFastJson(personList);
    long end=System.currentTimeMillis();
    Log.e("MainActivity","FastJson生成json數據 cost time---->"+(end-start));


    //FastJson解析json數據
    start=System.currentTimeMillis();
    List<Person> tempPersons=JsonUtils.jsonToListForFastJson(jsonData);
    end=System.currentTimeMillis();
    Log.e("MainActivity","FastJson解析json數據 cost time---->"+(end-start));

    //Gson生成json數據
     start=System.currentTimeMillis();
     jsonData=JsonUtils.objectToJsonForGson(personList);
     end=System.currentTimeMillis();
     Log.e("MainActivity","Gson生成json數據 cost time---->"+(end-start));

    //Gson解析json數據
    start=System.currentTimeMillis();
    List<Person> tempPersons1=JsonUtils.jsonToListForForGson(jsonData);
    end=System.currentTimeMillis();
    Log.e("MainActivity","Gson解析json數據 cost time---->"+(end-start));

重點看執行結果:單位毫秒(執行時間)

兩者轉換性能對比:1000條 10000條 100000條 200000條

fastJson : 45 289 4010 8396

Gson : 60 724 4071 8803

兩者解析性能對比:1000條 10000條 100000條 200000條

fastJson : 55 552 3826 8638

Gson : 45 465 5942 9668

總結:在數據量比較小的情況下,兩者性能相差無幾,在數據量比較大的情況下FastJson還是有優勢的。

插曲:為了項目省事,本人把FastJson給刪除了,結果項目中遺留了一些代碼編寫不規范的情況,比如userId 寫成了useid 但是json數據中返回的是userId,之前用FastJson一直正常這才發現原來FastJson對實體屬性是忽略大小寫的,真是一個神奇的東西。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容