json解析详解

http://blog.csdn.net/miaozhenzhong/article/details/52585726

JSON简介

  • JAVAScript Object Notation是一种轻量级的数据交换格式
  • 具有良好的可读和便于快速编写的特性。
  • 业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持)
  • JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。 – Json.org
  • JSON作为数据是目前网络中主流的数据传输格式之一,应用十分广泛,说是使用率达到99%一点也不勉强

JSON支持的数据类型

我们要学习使用JSON解析,必须对JSON解析的规则原理有深刻的认识和了解,然后才知道它的一个实现原理 
JSON里面的数据是以一种键值对的方式存在 
(”key”:”value”)中值的类型可以是下面数据类型中的任意一种: 
1. 数字(整数或浮点数) 
2. 逻辑值(true 或 false) 
3. 字符串(在双引号中) 
4. 数组(在方括号中) 
5. 函数 
6. 对象(在大括号中) 
7. null

JSON语法规则

JSON的语法规则非常的简单,就是使用 
大括号’{}’, 
中括号’[]’, 
逗号’,’, 
冒号’:’, 
双引号’“”’。

数据类型: 
嵌套对象、数组、字符串、数字、布尔值或空值。

我们在JSON解析中只有三中情况出现 
1.{} 解析’大括号’类型 
2. [ ] 解析是’中括号’类型 
3. 其实只有两种,那第三种则是1与2的组合方法即”{’name’:’李书豪’ ,’hobby’:[‘编程’,’电竞’,’睡觉’]}”那么下面分别来看一些这三种类型以及解析

JSON基本语法与图例

  • Object(对象类型) 
    • 用{ }包含一系列无序的key–Value键值对表示,其中Key和Value之间用冒号分割,每个key-value之间用逗号分割。
    • 比如:这里写图片描述
  • Array(数组类型) 
    • 使用[ ]包含所有元素,每个元素用逗号分隔,元素可以是任意的值
    • 比如:这里写图片描述
  • 组合形 
    • 这里写图片描述
      这里写图片描述

JSON数据解析

  • JSON解析一定要掌握的两条规则:

    • 1.如果看到是{ }–>使用JSONObject
    • 2.如果看到的[ ]–>使用JSONArray解析
  • 掌握了JSON的数据类型和基本语法后,下面我们将对JSON的各种语法类型进行详细解析(注意掌握两条规则的使用,掌握了JSON解析就那么回事)

纯对象(Object)的解析{ }:

 

[java] view plain copy
 
  1. import org.json.JSONException;  
  2. import org.json.JSONObject;  
  3.   
  4. /** 
  5.  * JSON-->纯对象(Object)的解析 
  6.  *  
  7.  * 注:我们在eclipse里面操作JSON解析的时候需要第三方jar包的支持 
  8.  * @author sKy° 
  9.  * @date 2016-5-8 
  10.  * @version 1.0 
  11.  */  
  12. public class Json01 {  
  13.     public static void main(String[] args) {  
  14. //      编辑一个我们要解析的数据对象  
  15. //     根据JSON的官方定义,键,加"",值,如果是字符串,就加"",其他不加。  
  16.         String json="{'name':'李书豪','age':24}";  
  17.   
  18.         try {  
  19. //          创建JSON解析对象(两条规则的体现:大括号用JSONObject,注意传入数据对象)  
  20.             JSONObject obj = new JSONObject(json);  
  21. //          obj.后面有各种数据类型,根据对象来选择使用的数据类型  
  22.             String name = obj.getString("name");  
  23. //          同理如上,这里的age为Int类型,我们就用对应的类型进行解析  
  24.             int age = obj.getInt("age");  
  25. //          最后输出到控制台  
  26.             System.out.println(name+"<--->"+age);  
  27.   
  28.         } catch (JSONException e) {  
  29.             e.printStackTrace();  
  30.         }  
  31.   
  32.     }  
  33. }  

 

这里写图片描述

纯数组(Array)的解析{ }:

[java] view plain copy
 
  1. import org.json.JSONArray;  
  2. import org.json.JSONException;  
  3.   
  4. /** 
  5.  * 对纯数组Aarry的解析 
  6.  * @author sKy° 
  7.  * @date 2016-5-8 
  8.  * @version 1.0 
  9.  */  
  10. public class Json02 {  
  11.     public static void main(String[] args) {  
  12. //      编辑一个我们要解析的数据对象  
  13.         String json="['天津冷','北京暖','东京热','南京凉']";  
  14.   
  15.         try {  
  16. //          创建JSON解析对象(两条规则的体现:中括号用JSONArray,注意传入数据对象)  
  17.             JSONArray jArray = new JSONArray(json);  
  18. //          取得数组长度  
  19.             int length = jArray.length();  
  20. //          回想数组的取值的方式? --->for循环遍历数组--->得到值  
  21.             for (int i = 0; i < length; i++) {  
  22. //              根据解析的数据类型使用该类型的get方法得到该值,打印输出  
  23.                 String string = jArray.getString(i);  
  24.                 System.out.print(string+",");  
  25.             }  
  26.   
  27.         } catch (JSONException e) {  
  28.             // TODO: handle exception  
  29.         }  
  30.   
  31.   
  32.     }  
  33. }  

 

这里写图片描述

组合类型的解析(一):

  • 例子: String json=”{‘name’:’李书豪’,’girlFriend’:{‘name’:’高圆圆’,’age’:18}}”;
  • 分析: 我们首先是解析外面的大括号的对象,然后,通过girlfFriend,获取到对应的被包含的里面大括号对象。所以这里我们需要建立一个类,封装对应的数据字段,根据setName ,setAge的方式在去得到对应的值
[java] view plain copy
 
  1. /** 
  2.  * 创建一个Person用于接收解析数据,封装对应字段 
  3.  * @author sKy° 
  4.  * @date 2016-5-8 
  5.  * @version 1.0 
  6.  */  
  7. public class Person {  
  8. //    分析我们要解析的对象,根据解析对象的属性值去创建对应的属性值  
  9. //    根据分析我们所要解析的对象,两条属性 1.name(String类型) 2.是girlFrien(类类型,意味着还需要在类中去嵌套一个类(创建类部类也可))  
  10.   
  11. //   封装字段  
  12.     private String name;  
  13.     private GirlFriend girlFriend;  //类类型  
  14. //   setter getter方法  
  15.     public String getName() {  
  16.         return name;  
  17.     }  
  18.     public void setName(String name) {  
  19.         this.name = name;  
  20.     }  
  21.     public GirlFriend getGirlFriend() {  
  22.         return girlFriend;  
  23.     }  
  24.     public void setGirlFriend(GirlFriend girlFriend) {  
  25.         this.girlFriend = girlFriend;  
  26.     }  
  27.   
  28. //   toString方法用于控制台输出  
  29.     @Override  
  30.     public String toString() {  
  31.         return "Person [name=" + name + ", girlFriend=" + girlFriend + "]";  
  32.     }  
  33.   
  34. }  
  35.   
  36. // 为了方便咱们看,这里就直接在下面创建了一个GirlFriend这个类  
  37. class GirlFriend{  
  38. //   根据对象属性值,创建对应的值  
  39.     private String name;  
  40.     private int age;  
  41. //   setter getter方法  
  42.     public String getName() {  
  43.         return name;  
  44.     }  
  45.     public void setName(String name) {  
  46.         this.name = name;  
  47.     }  
  48.     public int getAge() {  
  49.         return age;  
  50.     }  
  51.     public void setAge(int age) {  
  52.         this.age = age;  
  53.     }  
  54. //   toString方法用于控制台输出  
  55.     @Override  
  56.     public String toString() {  
  57.         return "GirlFriend [name=" + name + ", age=" + age + "]";  
  58.     }  
  59.   
  60.   
  61.   
  62. }  


开始解析:

[java] view plain copy
 
  1. import org.json.JSONException;  
  2. import org.json.JSONObject;  
  3.   
  4.   
  5.   
  6.   
  7.   
  8. /** 
  9.  * 组合数据类型的解析--->对象嵌套对象类型 
  10.  * @author sKy° 
  11.  * @date 2016-5-8 
  12.  * @version 1.0 
  13.  */  
  14. public class Json03 {  
  15.     public static void main(String[] args) {  
  16. //      编辑一个我们要解析的数据对象  
  17. //      分析: 应该先解析外面的大的对象,然后,通过girlfFriend,获取到对应的被包含的对象。  
  18. //      所以这里我们需要建立一个类,封装对应的数据字段,根据setName ,setAge的方式在去得到对应的值  
  19.   
  20.         String json="{'name':'李书豪','girlFriend':{'name':'高圆圆','age':18}}";  
  21.         try {  
  22. //          1.创建JSON解析对象(两条规则的提现:大括号用JSONObject,注意传入数据对象)  
  23.             JSONObject jObj = new JSONObject(json);  
  24. //          2.实例化Person对象获取对应的值--->这里是获得外面大括号{}的name值 思考?里面{}如何获得?  
  25.             Person per=new Person();  
  26.             String name = jObj.getString("name");  
  27.             per.setName(name);  
  28. //          3.分析:里面{}是嵌套在外面大括号类的所以我们解析的对象是通过外面大括号去取得里面大括号值,注意看  
  29.             //取得对应里面大括号的girlFriend,取得name值,赋值给girlFriend对象  
  30.             GirlFriend girlFriend=new GirlFriend();  
  31.             JSONObject jObj1 = jObj.getJSONObject("girlFriend");  
  32.             String gfName = jObj1.getString("name");  
  33.             girlFriend.setName(gfName);  
  34. //          获得age值并赋值  
  35.             int gfAge = jObj1.getInt("age");  
  36.             girlFriend.setAge(gfAge);  
  37. //          通过set把girlFriend的值赋Person 用于toString的输出,不然为空  
  38.             per.setGirlFriend(girlFriend);  
  39. //          输出  
  40.             System.out.println(per);  
  41.     }catch (JSONException e) {  
  42.         e.printStackTrace();  
  43.     }  
  44.     }  
  45. }  

 

这里写图片描述
小结: {[ {},{} ]}–>思路:第一步看到大括号:JSONObject去解,创建好对应里面的属性的值;第二步看到中括号:JSONArray去解析 对应创建好对应里面的属性值;第三步中括号里面的{},又是一个JSONObject。思路大致如此,强调注意的是,设置的属性值setXxx getXxx必须要和去获得值名称一致,不然会出错!!

组合类型的解析(二):

下面我们来解析一个略为复杂的JSON数据 
要解析的数据如下:

 

[java] view plain copy
 
  1. {  
  2.     'desc': 'OK',  
  3.     'status': 1000,  
  4.     'data': {  
  5.         'wendu': '20',  
  6.         'ganmao': '相对于今天将会出现大幅度降温,易发生感冒,请注意适当增加衣服,加强自我防护避免感冒。',  
  7.         'forecast': [  
  8.             {  
  9.                 'fengxiang': '北风',  
  10.                 'fengli': '3-4级',  
  11.                 'high': '高温 27℃',  
  12.                 'type': '中雨',  
  13.                 'low': '低温 19℃',  
  14.                 'date': '6日星期五'  
  15.             },  
  16.             {  
  17.                 'fengxiang': '北风',  
  18.                 'fengli': '微风级',  
  19.                 'high': '高温 23℃',  
  20.                 'type': '大雨',  
  21.                 'low': '低温 17℃',  
  22.                 'date': '7日星期六'  
  23.             },  
  24.             {  
  25.                 'fengxiang': '北风',  
  26.                 'fengli': '微风级',  
  27.                 'high': '高温 26℃',  
  28.                 'type': '小雨',  
  29.                 'low': '低温 17℃',  
  30.                 'date': '8日星期天'  
  31.             },  
  32.             {  
  33.                 'fengxiang': '南风',  
  34.                 'fengli': '微风级',  
  35.                 'high': '高温 27℃',  
  36.                 'type': '多云',  
  37.                 'low': '低温 15℃',  
  38.                 'date': '9日星期一'  
  39.             },  
  40.             {  
  41.                 'fengxiang': '南风',  
  42.                 'fengli': '微风级',  
  43.                 'high': '高温 29℃',  
  44.                 'type': '多云',  
  45.                 'low': '低温 16℃',  
  46.                 'date': '10日星期二'  
  47.             }  
  48.         ],  
  49.         'yesterday': {  
  50.             'fl': '微风',  
  51.             'fx': '北风',  
  52.             'high': '高温 33℃',  
  53.             'type': '阴',  
  54.             'low': '低温 22℃',  
  55.             'date': '5日星期四'  
  56.         },  
  57.         'aqi': '58',  
  58.         'city': '成都'  
  59.     }  
  60. }  

 

因为数据略大,不方便咱们看,这里给大家提供一个JSON在线解析工具http://json.phpddt.com/ 这是JSON在线高亮解析 ,可以很好的帮助咱们进行解析分析。下面是我用网页解析好的图片,可以思考下步骤(记住两条规则) 
这里写图片描述

分析: 
这里写图片描述
一:第一个大括号(JSONObject){”desc”: “status”: “data”} 
二:大括号里面有一个大括号(JSONObject){”wendu”: “20”, “ganmao”: “forecast”: “yesterday”: “aqi”: “city”: } 
三:第二个大括号里面有两个对象 1.数组形(JSONArray) 2.对象形( JSONObject ) 
而数组形里面又套有数组的对象{} 。这就需要咱们在解析的时候需要很细致的去创建对应的属性值,JSON解析并不难,而难受的地方就提现在对类的创建中,只要够细心也超简单!

开始封装字段:

 

[java] view plain copy
 
  1. import java.util.List;  
  2.   
  3. /** 
  4.  * 对应的字段的封装 
  5.  * @author sKy° 
  6.  * @date 2016-5-6 
  7.  * @version 1.0 
  8.  */  
  9. public class Weather {  
  10. //  外面大括号的字段封装 setter getter toString  
  11.     public String desc;  
  12.     public int status;  
  13.     public Data data;  
  14.     @Override  
  15.     public String toString() {  
  16.         return "Weather [desc=" + desc + ", status=" + status + ", data="  
  17.                 + data + "]";  
  18.     }  
  19.   
  20.   
  21. }  
  22.   
  23. class Data{  
  24. //  里面大括号的字段封装 setter getter toString   
  25. //  该类中包含有数组形和对象形,需要一并的封装在里面  
  26.     public String wendu;  
  27.     public String ganmao;  
  28.     public List<Forecast> forecast;  
  29.     public Yesterday yesterday;  
  30.     public String aqi;  
  31.     public String city;  
  32.     @Override  
  33.     public String toString() {  
  34.         return "Data [wendu=" + wendu + ", ganmao=" + ganmao + ", forecast="  
  35.                 + forecast + ", yesterday=" + yesterday + ", aqi=" + aqi  
  36.                 + ", city=" + city + "]";  
  37.     }  
  38.   
  39.   
  40. }  
  41.   
  42. class Forecast{  
  43. //  数组里面的大括号类型字段的封装  
  44.     public String fengxiang;  
  45.     public String fengli;  
  46.     public String high;  
  47.     public String type;   
  48.     public String low;  
  49.     public String date;  
  50.     @Override  
  51.     public String toString() {  
  52.         return "Forecast [fengxiang=" + fengxiang + ", fengli=" + fengli  
  53.                 + ", high=" + high + ", type=" + type + ", low=" + low  
  54.                 + ", date=" + date + "]";  
  55.     }  
  56.   
  57.   
  58. }  
  59. class Yesterday{  
  60. //   最后{}的字段封装  
  61.     public String fl;  
  62.     public String fx;  
  63.     public String high;  
  64.     public String type;  
  65.     public String low;  
  66.     public String date;  
  67.     @Override  
  68.     public String toString() {  
  69.         return "Yesterday [fl=" + fl + ", fx=" + fx + ", high=" + high  
  70.                 + ", type=" + type + ", low=" + low + ", date=" + date + "]";  
  71.     }  
  72.   
  73. }  

 

开始解析:

[java] view plain copy
 
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.   
  4. import org.json.JSONArray;  
  5. import org.json.JSONException;  
  6. import org.json.JSONObject;  
  7.   
  8.   
  9.   
  10.   
  11. /** 
  12.  * 组合类型二的解析 
  13.  * @author sKy° 
  14.  * @date 2016-5-6 
  15.  * @version 1.0 
  16.  */  
  17. public class Test01 {  
  18.     public static void main(String[] args) throws Exception {  
  19.   
  20.          //要解析的对象  
  21.         String json="{ 'desc': 'OK', 'status': 1000, 'data': { 'wendu': '20', 'ganmao': '相对于今天将会出现大幅度降温,易发生感冒,请注意适当增加衣服,加强自我防护避免感冒。', 'forecast': [ { 'fengxiang': '北风', 'fengli': '3-4级', 'high': '高温 27℃', 'type': '中雨', 'low': '低温 19℃', 'date': '6日星期五' }, { 'fengxiang': '北风', 'fengli': '微风级', 'high': '高温 23℃', 'type': '大雨', 'low': '低温 17℃', 'date': '7日星期六' }, { 'fengxiang': '北风', 'fengli': '微风级', 'high': '高温 26℃', 'type': '小雨', 'low': '低温 17℃', 'date': '8日星期天' }, { 'fengxiang': '南风', 'fengli': '微风级', 'high': '高温 27℃', 'type': '多云', 'low': '低温 15℃', 'date': '9日星期一' }, { 'fengxiang': '南风', 'fengli': '微风级', 'high': '高温 29℃', 'type': '多云', 'low': '低温 16℃', 'date': '10日星期二' } ], 'yesterday': { 'fl': '微风', 'fx': '北风', 'high': '高温 33℃', 'type': '阴', 'low': '低温 22℃', 'date': '5日星期四' }, 'aqi': '58', 'city': '成都' } }";  
  22.   
  23.         Weather wea=new Weather();  
  24. //      首先看到的是一个{}所以用JSON Object来进行解析  
  25. //      获得外部的Weather  
  26.         JSONObject obj = new JSONObject(json);  
  27.         String desc = obj.getString("desc");  
  28.         int status = obj.getInt("status");  
  29.         wea.status=status;  
  30.         wea.desc=desc;  
  31.   
  32. //      获得内部Data的数据  
  33.         JSONObject obj1 = obj.getJSONObject("data");  
  34.         Data data=new Data();  
  35.         data.wendu=obj1.getString("wendu");  
  36.         data.ganmao=obj1.getString("ganmao");  
  37.         data.aqi=obj1.getString("aqi");  
  38.         data.city=obj1.getString("city");  
  39.         wea.data=data;  
  40.         List<Forecast> forecasts=new ArrayList<>();  
  41.   
  42. //      获取forecast数组  
  43.         JSONArray jArr = obj1.getJSONArray("forecast");  
  44.         for (int i = 0; i < jArr.length(); i++) {  
  45.             JSONObject obj2 = jArr.getJSONObject(i);  
  46.             Forecast forecast=new Forecast();  
  47.             forecast.date=obj2.getString("date");  
  48.             forecast.fengxiang=obj2.getString("fengxiang");  
  49.             forecast.high=obj2.getString("high");  
  50.             forecast.low=obj2.getString("low");  
  51.             forecast.fengli=obj2.getString("fengli");  
  52.             forecast.type=obj2.getString("type");  
  53.             forecasts.add(forecast);  
  54.         }  
  55.         data.forecast=forecasts;  
  56.         JSONObject obj3 = obj1.getJSONObject("yesterday");  
  57.         Yesterday yesterday=new Yesterday();  
  58.         yesterday.fl=obj3.getString("fl");  
  59.         yesterday.fx=obj3.getString("fx");  
  60.         yesterday.high=obj3.getString("high");  
  61.         yesterday.type=obj3.getString("type");  
  62.         yesterday.low=obj3.getString("low");  
  63.         yesterday.date=obj3.getString("date");  
  64.         data.yesterday=yesterday;  
  65.   
  66. //      输出字段  
  67.         System.out.println(wea);  
  68.     }  

 

解析结果:

 

这里写图片描述

结语: 对于JSON解析个人的粗浅看法, 
1.首先是对JSON数据的一个分析 
2.其次是掌握JSON一些技巧(两条规则–对象形JSONObject ,数组形JSONArray) 
3.而后是对对应的属性值进行对应的字段封装建立对应的类(分析要细心,思路要清晰,程序这行需要有耐心不能浮躁) 
4.而后是解析中要有明确的思路

posted @ 2018-03-08 16:20  qqyong  阅读(937)  评论(0编辑  收藏  举报