Jason解析基础、 相关类库以及FastJSON、Gson和Jackson

来源:互联网 发布:mac ae英文版改中文版 编辑:程序博客网 时间:2024/06/05 15:01

1.json格式化验证

http://www.json.cn/


Json键值对里面的键一定要是字符串


2 Json转Bean 工具

http://www.atool.org/json2javabean.php


3 Json解析  看根目录是[]  还是{}     []使用JsonArray   否则使用JsonObject



4JsonReader  专门用于对流的直接解析   而一般的JsonArray,JsonObject是对字符串做的解析.

对于Object类型  选择reader.beginObject();     

                          //解析体

 reader.endObject();  


//解析体具体写法

while (reader.hasNext()) {    name = reader.nextName();    if (name.equals("artwork_url")) {        String artworkUrl = reader.nextString();//图片        mTrackObject.setArtworkUrl(artworkUrl);        Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: artworkwurl?" + artworkUrl);    } else if (name.equals("duration")) {        Long duration = reader.nextLong();  //时长        mTrackObject.setDuration(duration);        Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: duration?" + duration);    } else if (name.equals("user")) {        reader.skipValue();    } else {        reader.skipValue();    }}

对于Array类型  选择reader.beginArray();     

                          //解析体

 reader.endArray();  


//解析体具体写法

  while(reader.hasNext()){}   : 如果解析体有数据 

reader.nextName(); 
 Returns the next token  返回下一个解析键 并往下
解析
reader.nextString();   //nextLong  ,nextBoolean      etc.   返回下一个对应的解析值  并往下解析
reader.skipValue(); 跳过该值,并往下解析
//这行代码一定要行不然reader类不会对不匹配的键值对自动跳过 从而解析失败
else { reader.skipValue();}                                        

  

if (name.equals("collection")) {                        reader.beginArray();                        while (reader.hasNext()) {                            reader.beginObject();                            TrackObject mTrackObject = new TrackObject();                            mTrackObject.setGenre(genre);                            while (reader.hasNext()) {                                name = reader.nextName();                                if (name.equals("track")) {                                    reader.beginObject();                                    while (reader.hasNext()) {                                        name = reader.nextName();                                        if (name.equals("artwork_url")) {                                            String artworkUrl = reader.nextString();//图片                                            mTrackObject.setArtworkUrl(artworkUrl);                                                                               } else if (name.equals("user")) {                                            reader.skipValue();                                        } else {                                            reader.skipValue();                                        }                                    }                                    reader.endObject();//歌手暂时不加                                } else if (name.equals("score")) {                                    int score = reader.nextInt();                                                                 } else {                                    reader.skipValue();                                }                            }                            mTrackObject.setUsername("anymous");                                                     listTrackObjects.add(mTrackObject);                                                   reader.endObject();                        }                        reader.endArray();


 try {                JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));                String genre = null;                String kind = null;                reader.beginObject();                while (reader.hasNext()) {                    String name = reader.nextName();                    if (name.equals("genre")) {                        genre = reader.nextString();                        Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: genre??" + genre);                    } else if (name.equals("kind")) {                        kind = reader.nextString();                        Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: kind??" + kind);                    } else if (name.equals("collection")) {                        reader.beginArray();                        while (reader.hasNext()) {                            reader.beginObject();                            TrackObject mTrackObject = new TrackObject();                            mTrackObject.setGenre(genre);                            while (reader.hasNext()) {                                name = reader.nextName();                                if (name.equals("track")) {                                    reader.beginObject();                                    while (reader.hasNext()) {                                        name = reader.nextName();                                        if (name.equals("artwork_url")) {                                            String artworkUrl = reader.nextString();//图片                                            mTrackObject.setArtworkUrl(artworkUrl);                                            Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: artworkwurl?" + artworkUrl);                                        } else if (name.equals("duration")) {                                            Long duration = reader.nextLong();  //时长                                            mTrackObject.setDuration(duration);                                            Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: duration?" + duration);                                        } else if (name.equals("id")) {                                            mTrackObject.setId(reader.nextLong());                                        } else if (name.equals("permalink_url")) {                                            String permalinUrl = reader.nextString();//链接                                            mTrackObject.setPermalinkUrl(permalinUrl);                                            Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: permalink?" + permalinUrl);                                        } else if (name.equals("title")) {                                            String title = reader.nextString();  //歌名                                            mTrackObject.setTitle(title);                                            Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: title?" + title);                                        }/* else if (name.equals("uri")) {                                            String uri = reader.nextString();  //歌名                                            mTrackObject.setPermalinkUrl(uri);                                            Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: uri?" + uri);                                        } */ else if (name.equals("waveform_url")) {                                            String waveform_url = reader.nextString();  //波形                                            mTrackObject.setWaveForm(waveform_url);                                            Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: waveform_url?" + waveform_url);                                        } else if (name.equals("user")) {                                            reader.skipValue();                                        } else {                                            reader.skipValue();                                        }                                    }                                    reader.endObject();//歌手暂时不加                                } else if (name.equals("score")) {                                    int score = reader.nextInt();                                    Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: score??" + score);                                } else {                                    reader.skipValue();                                }                            }                            mTrackObject.setUsername("anymous");                            mTrackObject.setPlaybackCount(999);                            mTrackObject.setGenre(genre);                            mTrackObject.setStreamable(true);                            mTrackObject.setDownloadable(true);                            listTrackObjects.add(mTrackObject);                            Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: list size?" + listTrackObjects.size());                            reader.endObject();                        }                        reader.endArray();                    } else if (name.equals("last_updated")) {                        String last_updated = reader.nextString();                    }                }                reader.endObject();                reader.close();                Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre: listkk size??" + listTrackObjects.size());            } catch (Exception e) {                e.printStackTrace();                Log.d(TAG, "parsingListTrackObjectBySoundCloudGenre:  程序出错");            } finally {                if (in != null) {                    try {                        in.close();                    } catch (IOException e) {                        e.printStackTrace();                    }                }            }



对应 Json文件 :

{
    "genre":"soundcloud:genres:all-music",
    "kind":"top",
    "last_updated":"2017-04-04T08:07:33Z",
    "collection":[
        {
            "track":{
                "artwork_url":"https://i1.sndcdn.com/artworks-000209741436-qfq484-large.jpg",
                "commentable":true,
                "comment_count":5712,
                "created_at":"2017-02-26T22:16:38Z",
                "description":"LUV IS RAGE 2 COMING SOON",
                "downloadable":false,
                "download_count":0,
                "download_url":null,
                "duration":179948,
                "full_duration":179948,
                "embeddable_by":"all",
                "genre":"Alternative Rock",
                "has_downloads_left":true,
                "id":309689093,
                "kind":"track",
                "label_name":null,
                "last_modified":"2017-04-05T01:26:31Z",
                "license":"all-rights-reserved",
                "likes_count":704051,
                "permalink":"15-xo-tour-llif3",
                "permalink_url":"https://soundcloud.com/liluzivert/15-xo-tour-llif3",
                "playback_count":40332491,
                "public":true,
                "publisher_metadata":Object{...},
                "purchase_title":null,
                "purchase_url":null,
                "release_date":null,
                "reposts_count":79354,
                "secret_token":null,
                "sharing":"public",
                "state":"finished",
                "streamable":true,
                "tag_list":"",
                "title":"1.5- XO TOUR Llif3 (Produced By TM88)",
                "uri":"https://api.soundcloud.com/tracks/309689093",
                "urn":"soundcloud:tracks:309689093",
                "user_id":10494998,
                "visuals":null,
                "waveform_url":"https://wis.sndcdn.com/yUlUifyRZcZV_m.json",
                "display_date":"2017-02-26T22:16:38Z",
                "monetization_model":"NOT_APPLICABLE",
                "policy":"ALLOW",
                "user":{
                    "avatar_url":"http://a1.sndcdn.com/images/default_avatar_large.png?1491306653",
                    "first_name":"",
                    "full_name":"",
                    "id":10494998,
                    "kind":"user",
                    "last_modified":"2017-04-04T03:20:26Z",
                    "last_name":"",
                    "permalink":"liluzivert",
                    "permalink_url":"https://soundcloud.com/liluzivert",
                    "uri":"https://api.soundcloud.com/users/10494998",
                    "urn":"soundcloud:users:10494998",
                    "username":"LIL UZI VERT",
                    "verified":false,
                    "city":"PHILADELPHIA",
                    "country_code":"US"
                }

            }
,
            "score":6300458
        }
,
        {
            "track":Object{...},
            "score":4428696
        }
,
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...},
        Object{...}
    ]
,
    "query_urn":"soundcloud:charts:20e90a449de84c368d76fdc6a167ca02",
    "next_href":"https://api-v2.soundcloud.com/charts?genre=soundcloud%3Agenres%3Aall-music&query_urn=soundcloud%3Acharts%3A20e90a449de84c368d76fdc6a167ca02&offset=20&kind=top&limit=20"
}


5Json解析最全基础:




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
 print?在CODE上查看代码片派生到我的代码片
  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
 print?在CODE上查看代码片派生到我的代码片
  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
 print?在CODE上查看代码片派生到我的代码片
  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
 print?在CODE上查看代码片派生到我的代码片
  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
 print?在CODE上查看代码片派生到我的代码片
  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
 print?在CODE上查看代码片派生到我的代码片
  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
 print?在CODE上查看代码片派生到我的代码片
  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.而后是解析中要有明确的思路

(以上只是一个JSON初步的解析,但JSON解析的大致思路如此,后面有http套用的,无非也就把下载的文件转为JSON对象,后面解析思路也是如此,写的不好的地方大家包涵!有啥问题,欢迎留言!)



6 jackson,  gson ,fastjson 对比


Java对象转换Json的细节处理

前言

Java对象在转json的时候,如果对象里面有属性值为null的话,那么在json序列化的时候要不要序列出来呢?对比以下json转换方式

一、fastJson

1、fastJson在转换java对象为json的时候,默认是不序列化null值对应的key的

也就是说当对象里面的属性为空的时候,在转换成json时,不序列化那些为null值的属性

具体案例如下:
AutoPartsSearchRequest 有以下属性:


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args) {  
  2.         AutoPartsSearchRequest request = new AutoPartsSearchRequest();  
  3.         request.setKeywords("123");  
  4.         request.setSortingField("234242");  
  5.         String str = JSONObject.toJSONString(request);//fastjson默认转换是不序列化null值对应的key的  
  6.         System.out.println(str);  
  7.     }  

输出结果:{"keywords":"123","sortingField":"234242"}  , 没有序列化那些值为null的属性

2、但是如果想把null对应的key序列化出来呢? 

那就要仔细看看fastjson转换java对象为json的时候的入参了:也就是这个方法:

JSONObject.toJSONString(Object object, SerializerFeature... features)

Fastjson的SerializerFeature序列化属性:



[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. QuoteFieldNames———-输出key时是否使用双引号,默认为true   
  2. WriteMapNullValue——–是否输出值为null的字段,默认为false   
  3. WriteNullNumberAsZero—-数值字段如果为null,输出为0,而非null   
  4. WriteNullListAsEmpty—–List字段如果为null,输出为[],而非null   
  5. WriteNullStringAsEmpty—字符类型字段如果为null,输出为”“,而非null   
  6. WriteNullBooleanAsFalse–Boolean字段如果为null,输出为false,而非null  

结合上面,SerializerFeature... features是个数组,那么我们可以传入我们想要的参数,比如想序列化null,案例如下:
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args) {  
  2.         AutoPartsSearchRequest request = new AutoPartsSearchRequest();  
  3.         request.setKeywords("123");  
  4.         request.setSortingField("234242");  
  5.         String str = JSONObject.toJSONString(request, SerializerFeature.WriteMapNullValue);  
  6.         System.out.println(str);  
  7.     }  

输出结果如下:



3、想字符类型字段如果为null,转换输出为”“,而非null ,需要多加一个参数:WriteNullStringAsEmpty, 案例如下:


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args) {  
  2.         AutoPartsSearchRequest request = new AutoPartsSearchRequest();  
  3.         request.setKeywords("123");  
  4.         request.setSortingField("234242");  
  5.         String str = JSONObject.toJSONString(request, SerializerFeature.WriteMapNullValue,  
  6.                 SerializerFeature.WriteNullStringAsEmpty);  
  7.         System.out.println(str);  
  8.     }  

输出结果如下:







二、Jackson


1、jackson默认是序列化null对应的key的,也就是说不管你对象属性有没有值,在转换json的时候都会被序列化出来

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {  
  2.         AutoPartsSearchRequest request = new AutoPartsSearchRequest();  
  3.         request.setKeywords("123");  
  4.         request.setSortingField("234242");  
  5.         ObjectMapper mapper = new ObjectMapper();  
  6.         String str = mapper.writeValueAsString(request);   
  7.         System.out.println(str);  
  8.         //输出结果(此处就不格式化了):{"sortingField":"234242","partsClassifyId":null,"partsSubClassifyId":null,"sortingDirection":null:......  
  9.     }  


2、同理,想要不序列化null也是可以的,具体如下:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. 1.实体上  
  2.   
  3. @JsonInclude(Include.NON_NULL)   
  4.   
  5. //将该标记放在属性上,如果该属性为NULL则不参与序列化   
  6. //如果放在类上边,那对这个类的全部属性起作用   
  7. //Include.Include.ALWAYS 默认   
  8. //Include.NON_DEFAULT 属性为默认值不序列化   
  9. //Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化   
  10. //Include.NON_NULL 属性为NULL 不序列化   
  11.   
  12.   
  13. 2.代码上  
  14. ObjectMapper mapper = new ObjectMapper();  
  15.   
  16. mapper.setSerializationInclusion(Include.NON_NULL);    
  17.   
  18. //通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化   
  19. //Include.Include.ALWAYS 默认   
  20. //Include.NON_DEFAULT 属性为默认值不序列化   
  21. //Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化   
  22. //Include.NON_NULL 属性为NULL 不序列化   


注意:只对VO起作用,Map List不起作用,另外jackson还能过滤掉你设置的属性,具体的就各位自己去研究源码了

或者参照:jackson详解



三、Gson


1、gson和fastjson一样,默认是不序列化null值对应的key的,具体案例如下:


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {  
  2.         AutoPartsSearchRequest request = new AutoPartsSearchRequest();  
  3.         request.setKeywords("123");  
  4.         request.setSortingField("234242");  
  5.         Gson g = new GsonBuilder().create();  
  6.         String str = g.toJson(request);  
  7.         System.out.println(str);  
  8.         //输出结果:{"sortingField":"234242","keywords":"123"}  
  9.     }  


2、若是想序列化null值对应的key,只需要将以上创建代码改成以下代码就行:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. Gson g = new GsonBuilder().serializeNulls().create();  

案例就不写了


3、若是想转行null为空字符串"",则需要手动处理了


具体参考:gson转换null为空字符串


0 0