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阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容