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對實體屬性是忽略大小寫的,真是一個神奇的東西。