1. 程式人生 > >超詳細JSON解析步驟

超詳細JSON解析步驟

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)的解析{ }:

import org.json.JSONException;
import org.json.JSONObject;

/**
 * JSON-->純物件(Object)的解析
 * 
 * 注:我們在eclipse裡面操作JSON解析的時候需要第三方jar包的支援
 * @author sKy°
 * @date 2016-5-8
 * @version 1.0
 */
public class Json01 {
    public static void main(String[] args) {
//      編輯一個我們要解析的資料物件
//     根據JSON的官方定義,鍵,加"",值,如果是字串,就加"",其他不加。
        String json="{'name':'李書豪','age':24}";

        try {
//          建立JSON解析物件(兩條規則的體現:大括號用JSONObject,注意傳入資料物件)
            JSONObject obj = new JSONObject(json);
//          obj.後面有各種資料型別,根據物件來選擇使用的資料型別
            String name = obj.getString("name");
//          同理如上,這裡的age為Int型別,我們就用對應的型別進行解析
            int age = obj.getInt("age");
//          最後輸出到控制檯
            System.out.println(name+"<--->"+age);

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }
}

這裡寫圖片描述

純陣列(Array)的解析{ }:

import org.json.JSONArray;
import org.json.JSONException;

/**
 * 對純陣列Aarry的解析
 * @author sKy°
 * @date 2016-5-8
 * @version 1.0
 */
public class Json02 {
    public static void main(String[] args) {
//      編輯一個我們要解析的資料物件
        String json="['天津冷','北京暖','東京熱','南京涼']";

        try {
//          建立JSON解析物件(兩條規則的體現:中括號用JSONArray,注意傳入資料物件)
            JSONArray jArray = new JSONArray(json);
//          取得陣列長度
            int length = jArray.length();
//          回想陣列的取值的方式? --->for迴圈遍歷陣列--->得到值
            for (int i = 0; i < length; i++) {
//              根據解析的資料型別使用該型別的get方法得到該值,列印輸出
                String string = jArray.getString(i);
                System.out.print(string+",");
            }

        } catch (JSONException e) {
            // TODO: handle exception
        }


    }
}

這裡寫圖片描述

組合型別的解析(一):

  • 例子: String json=”{‘name’:’李書豪’,’girlFriend’:{‘name’:’高圓圓’,’age’:18}}”;
  • 分析: 我們首先是解析外面的大括號的物件,然後,通過girlfFriend,獲取到對應的被包含的裡面大括號物件。所以這裡我們需要建立一個類,封裝對應的資料欄位,根據setName ,setAge的方式在去得到對應的值
/**
 * 建立一個Person用於接收解析資料,封裝對應欄位
 * @author sKy°
 * @date 2016-5-8
 * @version 1.0
 */
public class Person {
//    分析我們要解析的物件,根據解析物件的屬性值去建立對應的屬性值
//    根據分析我們所要解析的物件,兩條屬性 1.name(String型別) 2.是girlFrien(類型別,意味著還需要在類中去巢狀一個類(建立類部類也可))

//   封裝欄位
    private String name;
    private GirlFriend girlFriend;  //類型別
//   setter getter方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public GirlFriend getGirlFriend() {
        return girlFriend;
    }
    public void setGirlFriend(GirlFriend girlFriend) {
        this.girlFriend = girlFriend;
    }

//   toString方法用於控制檯輸出
    @Override
    public String toString() {
        return "Person [name=" + name + ", girlFriend=" + girlFriend + "]";
    }

}

// 為了方便咱們看,這裡就直接在下面建立了一個GirlFriend這個類
class GirlFriend{
//   根據物件屬性值,建立對應的值
    private String name;
    private int age;
//   setter getter方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
//   toString方法用於控制檯輸出
    @Override
    public String toString() {
        return "GirlFriend [name=" + name + ", age=" + age + "]";
    }



}

開始解析:
import org.json.JSONException;
import org.json.JSONObject;





/**
 * 組合資料型別的解析--->物件巢狀物件型別
 * @author sKy°
 * @date 2016-5-8
 * @version 1.0
 */
public class Json03 {
    public static void main(String[] args) {
//      編輯一個我們要解析的資料物件
//      分析: 應該先解析外面的大的物件,然後,通過girlfFriend,獲取到對應的被包含的物件。
//      所以這裡我們需要建立一個類,封裝對應的資料欄位,根據setName ,setAge的方式在去得到對應的值

        String json="{'name':'李書豪','girlFriend':{'name':'高圓圓','age':18}}";
        try {
//          1.建立JSON解析物件(兩條規則的提現:大括號用JSONObject,注意傳入資料物件)
            JSONObject jObj = new JSONObject(json);
//          2.例項化Person物件獲取對應的值--->這裡是獲得外面大括號{}的name值 思考?裡面{}如何獲得?
            Person per=new Person();
            String name = jObj.getString("name");
            per.setName(name);
//          3.分析:裡面{}是巢狀在外面大括號類的所以我們解析的物件是通過外面大括號去取得裡面大括號值,注意看
            //取得對應裡面大括號的girlFriend,取得name值,賦值給girlFriend物件
            GirlFriend girlFriend=new GirlFriend();
            JSONObject jObj1 = jObj.getJSONObject("girlFriend");
            String gfName = jObj1.getString("name");
            girlFriend.setName(gfName);
//          獲得age值並賦值
            int gfAge = jObj1.getInt("age");
            girlFriend.setAge(gfAge);
//          通過set把girlFriend的值賦Person 用於toString的輸出,不然為空
            per.setGirlFriend(girlFriend);
//          輸出
            System.out.println(per);
    }catch (JSONException e) {
        e.printStackTrace();
    }
    }
}

這裡寫圖片描述
小結: {[ {},{} ]}–>思路:第一步看到大括號:JSONObject去解,建立好對應裡面的屬性的值;第二步看到中括號:JSONArray去解析 對應建立好對應裡面的屬性值;第三步中括號裡面的{},又是一個JSONObject。思路大致如此,強調注意的是,設定的屬性值setXxx getXxx必須要和去獲得值名稱一致,不然會出錯!!

組合型別的解析(二):

下面我們來解析一個略為複雜的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': '成都'
    }
}

因為資料略大,不方便咱們看,這裡給大家提供一個JSON線上解析工具http://json.phpddt.com/ 這是JSON線上高亮解析 ,可以很好的幫助咱們進行解析分析。下面是我用網頁解析好的圖片,可以思考下步驟(記住兩條規則)
這裡寫圖片描述

分析:
這裡寫圖片描述
一:第一個大括號(JSONObject){”desc”: “status”: “data”}
二:大括號裡面有一個大括號(JSONObject){”wendu”: “20”, “ganmao”: “forecast”: “yesterday”: “aqi”: “city”: }
三:第二個大括號裡面有兩個物件 1.陣列形(JSONArray) 2.物件形( JSONObject )
而陣列形裡面又套有陣列的物件{} 。這就需要咱們在解析的時候需要很細緻的去建立對應的屬性值,JSON解析並不難,而難受的地方就提現在對類的建立中,只要夠細心也超簡單!

開始封裝欄位
import java.util.List;

/**
 * 對應的欄位的封裝
 * @author sKy°
 * @date 2016-5-6
 * @version 1.0
 */
public class Weather {
//  外面大括號的欄位封裝 setter getter toString
    public String desc;
    public int status;
    public Data data;
    @Override
    public String toString() {
        return "Weather [desc=" + desc + ", status=" + status + ", data="
                + data + "]";
    }


}

class Data{
//  裡面大括號的欄位封裝 setter getter toString 
//  該類中包含有陣列形和物件形,需要一併的封裝在裡面
    public String wendu;
    public String ganmao;
    public List<Forecast> forecast;
    public Yesterday yesterday;
    public String aqi;
    public String city;
    @Override
    public String toString() {
        return "Data [wendu=" + wendu + ", ganmao=" + ganmao + ", forecast="
                + forecast + ", yesterday=" + yesterday + ", aqi=" + aqi
                + ", city=" + city + "]";
    }


}

class Forecast{
//  數組裡面的大括號型別欄位的封裝
    public String fengxiang;
    public String fengli;
    public String high;
    public String type; 
    public String low;
    public String date;
    @Override
    public String toString() {
        return "Forecast [fengxiang=" + fengxiang + ", fengli=" + fengli
                + ", high=" + high + ", type=" + type + ", low=" + low
                + ", date=" + date + "]";
    }


}
class Yesterday{
//   最後{}的欄位封裝
    public String fl;
    public String fx;
    public String high;
    public String type;
    public String low;
    public String date;
    @Override
    public String toString() {
        return "Yesterday [fl=" + fl + ", fx=" + fx + ", high=" + high
                + ", type=" + type + ", low=" + low + ", date=" + date + "]";
    }

}

開始解析:

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;




/**
 * 組合型別二的解析
 * @author sKy°
 * @date 2016-5-6
 * @version 1.0
 */
public class Test01 {
    public static void main(String[] args) throws Exception {

         //要解析的物件
        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': '成都' } }";

        Weather wea=new Weather();
//      首先看到的是一個{}所以用JSON Object來進行解析
//      獲得外部的Weather
        JSONObject obj = new JSONObject(json);
        String desc = obj.getString("desc");
        int status = obj.getInt("status");
        wea.status=status;
        wea.desc=desc;

//      獲得內部Data的資料
        JSONObject obj1 = obj.getJSONObject("data");
        Data data=new Data();
        data.wendu=obj1.getString("wendu");
        data.ganmao=obj1.getString("ganmao");
        data.aqi=obj1.getString("aqi");
        data.city=obj1.getString("city");
        wea.data=data;
        List<Forecast> forecasts=new ArrayList<>();

//      獲取forecast陣列
        JSONArray jArr = obj1.getJSONArray("forecast");
        for (int i = 0; i < jArr.length(); i++) {
            JSONObject obj2 = jArr.getJSONObject(i);
            Forecast forecast=new Forecast();
            forecast.date=obj2.getString("date");
            forecast.fengxiang=obj2.getString("fengxiang");
            forecast.high=obj2.getString("high");
            forecast.low=obj2.getString("low");
            forecast.fengli=obj2.getString("fengli");
            forecast.type=obj2.getString("type");
            forecasts.add(forecast);
        }
        data.forecast=forecasts;
        JSONObject obj3 = obj1.getJSONObject("yesterday");
        Yesterday yesterday=new Yesterday();
        yesterday.fl=obj3.getString("fl");
        yesterday.fx=obj3.getString("fx");
        yesterday.high=obj3.getString("high");
        yesterday.type=obj3.getString("type");
        yesterday.low=obj3.getString("low");
        yesterday.date=obj3.getString("date");
        data.yesterday=yesterday;

//      輸出欄位
        System.out.println(wea);
    }

解析結果:

這裡寫圖片描述

結語: 對於JSON解析個人的粗淺看法,
1.首先是對JSON資料的一個分析
2.其次是掌握JSON一些技巧(兩條規則–物件形JSONObject ,陣列形JSONArray)
3.而後是對對應的屬性值進行對應的欄位封裝建立對應的類(分析要細心,思路要清晰,程式這行需要有耐心不能浮躁)
4.而後是解析中要有明確的思路

(以上只是一個JSON初步的解析,但JSON解析的大致思路如此,後面有http套用的,無非也就把下載的檔案轉為JSON物件,後面解析思路也是如此,寫的不好的地方大家包涵!有啥問題,歡迎留言!)