Android開發(fā):JSON簡(jiǎn)介及最全面解析方法(Gson、AS自帶org.json、Jackson解析)

轉(zhuǎn)載:http://www.itdecent.cn/p/b87fee2f7a23

前言

今天,我們來介紹現(xiàn)今主流的數(shù)據(jù)交換格式-JSON!
同樣作為主流為數(shù)據(jù)交換格式-XML,如果有興趣可以閱讀我寫的XML及其DOM、SAX、PULL解析方法和對(duì)比

目錄

JSON簡(jiǎn)介&解析方法介紹.png

定義

JavaScript Object Notation,JavaScript的對(duì)象表示法,是一種輕量級(jí)的文本數(shù)據(jù)交換格式。

作用

用于數(shù)據(jù)的標(biāo)記、存儲(chǔ)和傳輸。

特點(diǎn)

  • 輕量級(jí)的文本數(shù)據(jù)交換格式
  • 獨(dú)立于語言和平臺(tái)
  • 具有自我描述性
  • 讀寫速度快,解析簡(jiǎn)單

語法

JSON值

  • 名稱/值
  • 數(shù)組
  • 對(duì)象

JSON實(shí)例

{"skill":{
          "web":[
                 {
                  "name":"html",
                  "year":"5"
                 },
                 {
                  "name":"ht",
                  "year":"4"
                 }],
           "database":[
                  {
                  "name":"h",
                  "year":"2"
                 }]
`}}

“名稱/值”對(duì)無序、一個(gè)對(duì)象用“{}”包括,名稱和值間用“:”相隔,對(duì)象間用“,”隔開;
"name":"html"

對(duì)象一個(gè)JSON對(duì)象包括多個(gè)名稱/值對(duì),在花括號(hào)里書寫
{ "name":"html","year":"5"}

數(shù)組數(shù)組以“[]”包括,數(shù)據(jù)的對(duì)象用逗號(hào)隔開
[{ "name":"html", "year":"5" }, { "name":"ht", "year":"4" }]

web和database都是一個(gè)數(shù)組

語法總結(jié)

數(shù)組 [ 對(duì)象 { 值/對(duì)"" } ]

數(shù)組包含對(duì)象,對(duì)象包含值/對(duì)

JSON解析

在了解了JSON后,是時(shí)候來看下如何在Android解析JSON數(shù)據(jù)

解析方法

Android解析JSON數(shù)據(jù)的方法和XML解析類似,主要有兩種:基于事件驅(qū)動(dòng)基于文檔驅(qū)動(dòng)解析方式

基于事件驅(qū)動(dòng)

主流方式:Gson解析和Jackson解析

Gson介紹

  • 簡(jiǎn)介:使用谷歌的開源庫(kù)進(jìn)行解析
  • 解析方式:基于事件驅(qū)動(dòng),根據(jù)所需要取的數(shù)據(jù)通過建立一個(gè)對(duì)應(yīng)于JSON數(shù)據(jù)的JavaBean類就可以通過簡(jiǎn)單的操作解析出所需JSON數(shù)據(jù)
Gson解析

步驟1:創(chuàng)建一個(gè)與JSON數(shù)據(jù)對(duì)應(yīng)的JavaBean類(用作存儲(chǔ)需要解析的數(shù)據(jù))GSON解析的關(guān)鍵是重點(diǎn)是要根據(jù)json數(shù)據(jù)里面的結(jié)構(gòu)寫出一個(gè)對(duì)應(yīng)的javaBean,規(guī)則是:
JSON的大括號(hào)對(duì)應(yīng)一個(gè)對(duì)象,對(duì)象里面有key和value(值)。在JavaBean里面的類屬性要和key同名。
JSON的方括號(hào)對(duì)應(yīng)一個(gè)數(shù)組,所以在JavaBeanBean里面對(duì)應(yīng)的也是數(shù)組,數(shù)據(jù)里面可以有值或者對(duì)象。
如果數(shù)組里面只有值沒有key,就說明它只是一個(gè)純數(shù)組,如果里面有值有key,則說明是對(duì)象數(shù)組。純數(shù)組對(duì)應(yīng)JavaBean里面的數(shù)組類型,對(duì)象數(shù)組要在Bean里面建立一個(gè)內(nèi)部類,類屬性就是對(duì)應(yīng)的對(duì)象里面的key,建立了之后要?jiǎng)?chuàng)建一個(gè)這個(gè)內(nèi)部類的對(duì)象,名字對(duì)應(yīng)數(shù)組名。
對(duì)象里面嵌套對(duì)象時(shí)候,也要建立一個(gè)內(nèi)部類,和對(duì)象數(shù)組一樣,這個(gè)內(nèi)部類對(duì)象的名字就是父對(duì)象的key

注:JavaBean類里的屬性不一定要全部和JSON數(shù)據(jù)里的所有key相同,可以按需取數(shù)據(jù),也就是你想要哪種數(shù)據(jù),就把對(duì)應(yīng)的key屬性寫出來,注意名字一定要對(duì)應(yīng)
以下有兩個(gè)JSON文檔來說明創(chuàng)建JavaBean類的創(chuàng)建方法
簡(jiǎn)單的JSON數(shù)據(jù)1(對(duì)象)
String json = "{\"id\":1,\"name\":\"小明\",\"sex\":\"男\(zhòng)",\"age\":18,\"height\":175}";

步驟1:創(chuàng)建簡(jiǎn)單的JSON數(shù)據(jù)對(duì)應(yīng)的JavaBean類

package scut.learngson;

public class EntityStudent {
    private int id;
    private String name;
    private String sex;
    private int age;
    private int height;

    public void setId(int id){
        this.id = id;
    }
    public void setName(String name){
        this.name = name;
    }
    public void setSex(String sex){
        this.sex = sex;
    }
    public void setAge(int age){
        this.age = age;
    }
    public void setHeight(int height){
        this.height = height;
    }
    public int getId(){
        return id;
    }
    public String getName(){
        return name;
    }
    public String getSex(){
        return sex;
    }
    public int getAge(){
        return age;
    }
    public int getHeight(){
        return  height;
    }
    public void show(){
                System.out.print("id=" + id + ",");
                System.out.print("name=" + name+",");
                System.out.print("sex=" + sex+",");
                System.out.print("age=" + age+",");
                System.out.println("height=" + height + ",");

    }
}

復(fù)雜的JSON數(shù)據(jù)(具備嵌套)

{"translation":["車"],
  "basic":
    {
      "phonetic":"kɑ?",
      "explains":["n. 汽車;車廂","n. (Car)人名;(土)賈爾;(法、西)卡爾;(塞)察爾"]},
  "query":"car",
  "errorCode":0,
  "web":[{"value":["汽車","車子","小汽車"],"key":"Car"},
         {"value":["概念車","概念車","概念汽車"],"key":"concept car"},
         {"value":["碰碰車","碰撞用汽車","碰碰汽車"],"key":"bumper car"}]
}

步驟1:復(fù)雜的JSON數(shù)據(jù)對(duì)應(yīng)的JavaBean類

package scut.httpgson;
import java.util.List;

public class student {
    public String[] translation;      //["車"]數(shù)組
    public basic basic;                //basic對(duì)象里面嵌套著對(duì)象,創(chuàng)建一個(gè)basic內(nèi)部類對(duì)象
    public  static class basic{        //建立內(nèi)部類
        public String phonetic;
        public String[] explains;
    }
    public String query;
    public int errorCode;
    public List<wb> web;            //web是一個(gè)對(duì)象數(shù)組,創(chuàng)建一個(gè)web內(nèi)部類對(duì)象
    public static class wb{            
            public String[] value;
            public String key;
        }

    public void show(){
        //輸出數(shù)組
        for (int i = 0;i<translation.length;i++)
        {
        System.out.println(translation[i]);
        }
        //輸出內(nèi)部類對(duì)象
        System.out.println(basic.phonetic);
        //輸出內(nèi)部類數(shù)組
        for (int i = 0;i<basic.explains.length;i++){
            System.out.println(basic.explains[i]);
        }
        System.out.println(query);
        System.out.println(errorCode);
        for (int i = 0;i<web.size();i++){
            for(int j = 0; j<web.get(i).value.length;j++)
            {
                System.out.println(web.get(i).value[j]);
            }
            System.out.println(web.get(i).key);
        }
    }
    }

好了,是不是覺得根據(jù)JSON文本數(shù)據(jù)去轉(zhuǎn)換成JavaBean實(shí)體類很復(fù)雜呢?其實(shí)還有個(gè)簡(jiǎn)單的方法,請(qǐng)使用在線JSON字符串轉(zhuǎn)Java實(shí)體類,哈哈請(qǐng)不要打我,繼續(xù)往下看吧!

步驟2:下載并導(dǎo)入GSON需要的庫(kù)
別翻墻去谷歌官網(wǎng)下了,點(diǎn)這吧
步驟3:用Gson進(jìn)行轉(zhuǎn)換
package scut.learngson;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import com.google.gson.Gson;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Gson gson = new Gson(); //創(chuàng)建JavaBean類的對(duì)象 Student student = new EntityStudent(); String json = "{"id":1,"name":"小明","sex":"男","age":18,"height":175}"; //用GSON方法將JSON數(shù)據(jù)轉(zhuǎn)為單個(gè)類實(shí)體 student = gson.fromJson(json,Student.class); //調(diào)用student方法展示解析的數(shù)據(jù) student.show(); //將Java集合轉(zhuǎn)換為json String json2 = gson.toJson(List); System.out.println(json2); }}

總結(jié)
可以看到,利用GSON方法進(jìn)行解析,關(guān)鍵在于根據(jù)json數(shù)據(jù)里面的結(jié)構(gòu)寫出一個(gè)對(duì)應(yīng)的javaBean,而解析過程非常簡(jiǎn)單:
JavaBean對(duì)象 = gson.fromJson(son,javaBean類類名.class);

Jackson解析
解析原理:基于事件驅(qū)動(dòng),與GSON相同,先創(chuàng)建一個(gè)對(duì)應(yīng)于JSON數(shù)據(jù)的JavaBean類就可以通過簡(jiǎn)單的操作解析出所需JSON數(shù)據(jù)。但和Gson解析不同的是,GSON可按需解析,即創(chuàng)建的JavaBean類不一定完全涵蓋所要解析的JSON數(shù)據(jù),按需創(chuàng)建屬性,但Jackson解析對(duì)應(yīng)的JavaBean必須把Json數(shù)據(jù)里面的所有key都有所對(duì)應(yīng),即必須把JSON內(nèi)的數(shù)據(jù)所有解析出來,無法按需解析。但Jackson的解析速度和效率都要比GSON高

核心代碼

JSON數(shù)據(jù)
{"student": [ {"id":1,"name":"小明","sex":"男","age":18,"height":175,"date":[2013,8,11]}, {"id":2,"name":"小紅","sex":"女","age":19,"height":165,"date":[2013,8,23]}, {"id":3,"name":"小強(qiáng)","sex":"男","age":20,"height":185,"date":[2013,9,1]} ], "grade":"2"}

步驟1:建立對(duì)應(yīng)的javaBean:
建立javaBean的對(duì)應(yīng)規(guī)則和GSON一樣
package scut.learnjackson;import java.util.ArrayList;import java.util.List;class test { private List<stu> student = new ArrayList<stu>(); private int grade; public void setStudent(List<stu> student){ this.student = student; } public List<stu> getStudent(){ return student; } public void setGrade(int grade){ this.grade = grade; } public int getGrade(){ return grade; } private static class stu { private int id; private String name; private String sex; private int age; private int height; private int[] date; public void setId(int id){ this.id = id; } public int getId(){ return id; } public void setName(String name){ this.name = name; } public String getName(){ return name; } public void setSex(String sex){ this.sex = sex; } public String getSex(){ return sex; } public void setAge(int age){ this.age = age; } public int getAge(){ return age; } public void setHeight(int height){ this.height = height; } public int getHeight(){ return height; } public void setDate(int[] date){ this.date = date; } public int[] getDate(){ return date; } } public String tostring(){ String str = ""; for (int i = 0;i<student.size();i++){ str += student.get(i).getId() + " " + student.get(i).getName() + " " + student.get(i).getSex() + " " + student.get(i).getAge() + " " + student.get(i).getHeight() ; for (int j = 0;j<student.get(i).getDate().length;j++) { str += student.get(i).getDate()[j]+ " " ; } str += "\n"; } str += "\n"+getGrade(); return str; }}

步驟2:利用Jackson方法進(jìn)行解析
package scut.learnjackson;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import org.codehaus.jackson.map.ObjectMapper;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ObjectMapper objectMapper = new ObjectMapper(); try { InputStreamReader isr = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("assets/" + "student.json"),"utf-8"); //從assets獲取json文件 BufferedReader bfr = new BufferedReader(isr); String line; StringBuilder stringBuilder = new StringBuilder(); while ((line = bfr.readLine())!=null){ stringBuilder.append(line); }//將JSON數(shù)據(jù)轉(zhuǎn)化為字符串 System.out.println(stringBuilder.toString()); System.out.println(tes.tostring()); } catch (IOException e) { e.printStackTrace(); } }}

基于文檔驅(qū)動(dòng)解析方式
主流方式:Android Studio自帶org.json解析
解析方式:基于文檔驅(qū)動(dòng),類似于XML的DOM解析方法,先把全部文件讀入到內(nèi)存中,然后遍歷所有數(shù)據(jù),然后根據(jù)需要檢索想要的數(shù)據(jù)。

需要解析的JSON數(shù)據(jù):
{"student":[ {"id":1,"name":"小明","sex":"男","age":18,"height":175}, {"id":2,"name":"小紅","sex":"女","age":19,"height":165}, {"id":3,"name":"小強(qiáng)","sex":"男","age":20,"height":185} ],"cat":"it"}

讀入本地assets文件夾里面的student.son并解析
package scut.learngson;import android.os.Bundle;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EntityStudent student = new EntityStudent(); try { //從assets獲取json文件 InputStreamReader isr = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("assets/" + "student.json")); //字節(jié)流轉(zhuǎn)字符流 BufferedReader bfr = new BufferedReader(isr); String line ; StringBuilder stringBuilder = new StringBuilder(); while ((line = bfr.readLine())!=null){ stringBuilder.append(line); }//將JSON數(shù)據(jù)轉(zhuǎn)化為字符串 JSONObject root = new JSONObject(stringBuilder.toString()); //根據(jù)鍵名獲取鍵值信息 System.out.println("root:"+root.getString("cat")); JSONArray array = root.getJSONArray("student"); for (int i = 0;i < array.length();i++) { JSONObject stud = array.getJSONObject(i); System.out.println("------------------"); System.out.print("id="+stud.getInt("id")+ ",")); System.out.print("name="+stud.getString("name")+ ",")); System.out.print("sex="+stud.getString("sex")+ ",")); System.out.print("age="+stud.getInt("age")+ ",")); System.out.println("height="+stud.getInt("height")+ ",")); bfr.close(); isr.close(); is.close();//依次關(guān)閉流 } } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } }}

GSON、Jackson、Android Studio自帶org.son解析三類方式對(duì)比
Android Studio自帶org.json
原理:基于文檔驅(qū)動(dòng)
特點(diǎn):優(yōu)點(diǎn):無缺點(diǎn):解析 XML 文件時(shí)會(huì)將整個(gè) XML 文件的內(nèi)容解析成樹型結(jié)構(gòu)存放在內(nèi)存中并創(chuàng)建新對(duì)象,比較消耗時(shí)間和內(nèi)存,解析速度和效率慢,解析方式和性能完敗GSON

GSON方式
原理:基于事件驅(qū)動(dòng)
特點(diǎn):優(yōu)點(diǎn):解析方法簡(jiǎn)單、解析效率高、占存少、靈活性高
使用情境適用于需要處理大型 JSON文檔、JSON文檔結(jié)構(gòu)復(fù)雜的場(chǎng)合

Jackson方式
原理:基于事件驅(qū)動(dòng)
特點(diǎn):優(yōu)點(diǎn):解析效率最高、在數(shù)據(jù)量大的情況優(yōu)勢(shì)尤為明顯、占存少缺點(diǎn):必須完全解析文檔,如果要按需解析的話可以拆分Json來讀取,操作和解析方法復(fù)雜;
使用情境適用于需要處理超大型JSON文檔、不需要對(duì)JSON文檔進(jìn)行按需解析、、性能要求較高的場(chǎng)合

與XML解析對(duì)比
對(duì)于同樣作為主流的數(shù)據(jù)交換格式來說,JSON相比于XML,JSON文檔大小更加小,解析方法更加簡(jiǎn)單、讀寫速度更快,所以JSON一定是你在數(shù)據(jù)交換格式的選型中的首選。
總結(jié)
本文對(duì)現(xiàn)今主流的數(shù)據(jù)傳輸格式JSON進(jìn)行了全面介紹。接下來我會(huì)介紹繼續(xù)介紹Android開發(fā)中的相關(guān)知識(shí),有興趣可以繼續(xù)關(guān)注Carson_Ho的安卓開發(fā)筆記
請(qǐng)點(diǎn)贊!因?yàn)槟銈兊墓膭?lì)是我寫作的最大動(dòng)力!
相關(guān)文章閱讀Android開發(fā):Handler異步通信機(jī)制全面解析(包含Looper、Message Queue)Android開發(fā):最全面、最易懂的Android屏幕適配解決方案Android開發(fā):5分鐘解析Activity&Fragment生命周期Android開發(fā):JSON簡(jiǎn)介及最全面解析方法!Android開發(fā):XML簡(jiǎn)介及DOM、SAX、PULL解析對(duì)比

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 現(xiàn)今最主流的數(shù)據(jù)交換格式 非 JSON莫屬 今天,我將全面介紹 JSON & 解析方式(Gson、AS自帶o...
    Carson帶你學(xué)安卓閱讀 36,875評(píng)論 20 231
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,822評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,688評(píng)論 19 139
  • 9.29(八月初十)星期五 陰有小雨 手臂再次酸痛,今晚只能少寫。 【班主任會(huì)議發(fā)言——天天遇見最好的...
    五月的草莓閱讀 358評(píng)論 0 0
  • 為什么總是夜深人靜的時(shí)候喜歡寫字?可時(shí)夜半時(shí)卻已常常人困馬乏,但是我真切地感受到只有這個(gè)時(shí)候,哪怕15分鐘也能讓...
    曉蘭sally閱讀 392評(píng)論 0 0

友情鏈接更多精彩內(nèi)容