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

2023-12-06 12:40

本文主要是介绍Jason解析基础、 相关类库以及FastJSON、Gson和Jackson,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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为空字符串


这篇关于Jason解析基础、 相关类库以及FastJSON、Gson和Jackson的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/461859

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚: