前言
- 現(xiàn)今最主流的數(shù)據(jù)交換格式 非
JSON
莫屬 - 今天,我將全面介紹
JSON
& 解析方式(Gson
、AS
自帶org.json
、Jackson
),希望你們會(huì)喜歡
關(guān)于另外1種主流的數(shù)據(jù)傳輸格式
XML
,具體請(qǐng)看:Carson帶你學(xué)序列化:深入分析XML多種解析方式(DOM、SAX、PULL)
目錄
示意圖
1. 簡(jiǎn)介
示意圖
2. 語(yǔ)法
- 1個(gè)JSON文件里含多個(gè)數(shù)據(jù),這些數(shù)據(jù) 以
JSON
值 的形式 存在
// JSON實(shí)例
{"skill":{
"web":[
{
"name":"html",
"year":"5"
},
{
"name":"ht",
"year":"4"
}],
"database":[
{
"name":"h",
"year":"2"
}]
`}}
- 1個(gè)
JSON
值的內(nèi)容形式可以是:”名稱 - 值“對(duì)、數(shù)組 或 對(duì)象,下面將詳細(xì)說明
示意圖
3. 解析方式
-
Android
解析JSON
數(shù)據(jù)的方式 類似XML
解析,主要分為2大類:
示意圖 下面,我將詳細(xì)介紹每種方式
3.1 Android Studio自帶org.json解析
- 解析原理:基于文檔驅(qū)動(dòng)
類似于
XML
的DOM
解析方式
- 解析流程:把全部文件讀入到內(nèi)存中 ->> 遍歷所有數(shù)據(jù) ->> 根據(jù)需要檢索想要的數(shù)據(jù)
- 具體使用
// 創(chuàng)建需解析的JSON數(shù)據(jù):student.json
// 將該文件放入到本地assets文件夾里
{
"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"
}
// 具體解析
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();
}
}
}
3.2 Gson解析
- 解析原理:基于事件驅(qū)動(dòng)
- 解析流程:根據(jù)所需取的數(shù)據(jù) 建立1個(gè)對(duì)應(yīng)于
JSON
數(shù)據(jù)的JavaBean
類,即可通過簡(jiǎn)單操作解析出所需數(shù)據(jù) - 具體使用
步驟1:創(chuàng)建一個(gè)與JSON數(shù)據(jù)對(duì)應(yīng)的JavaBean類(用作存儲(chǔ)需要解析的數(shù)據(jù))
Gson
解析的關(guān)鍵 = 根據(jù)JSON
數(shù)據(jù) 寫出一個(gè)對(duì)應(yīng)的JavaBean
,規(guī)則是:
示意圖
下面用2個(gè)例子說明 如何通過JSON
文檔創(chuàng)建JavaBean
類
/**
* 簡(jiǎn)單轉(zhuǎn)換
*/
// JSON數(shù)據(jù)1
String json = "{\"id\":1,\"name\":\"小明\",\"sex\":\"男\(zhòng)",\"age\":18,\"height\":175}";
// 對(duì)應(yīng)的JavaBean類
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ù)雜轉(zhuǎn)換
*/
// JSON數(shù)據(jù)2(具備嵌套)
{"translation":["車"],
"basic":
{
"phonetic":"kɑ?",
"explains":["n. 汽車;車廂","n. (Car)人名;(土)賈爾;(法、西)卡爾;(塞)察爾"]},
"query":"car",
"errorCode":0,
"web":[{"value":["汽車","車子","小汽車"],"key":"Car"},
{"value":["概念車","概念車","概念汽車"],"key":"concept car"},
{"value":["碰碰車","碰撞用汽車","碰碰汽車"],"key":"bumper car"}]
}
// 對(duì)應(yīng)的復(fù)雜的JSON數(shù)據(jù)對(duì)應(yīng)的JavaBean類
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);
}
}
}
若覺得轉(zhuǎn)換過于復(fù)雜,請(qǐng)直接使用工具:JSON字符串 轉(zhuǎn) Java實(shí)體類
步驟2:導(dǎo)入GSON庫(kù)
在Android Gradle
導(dǎo)入依賴
dependencies {
compile 'com.google.code.gson:gson:2.3.1'
}
步驟3:使用Gson進(jìn)行解析
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1. 創(chuàng)建Gson對(duì)象
Gson gson = new Gson();
// 2. 創(chuàng)建JavaBean類的對(duì)象
Student student = new EntityStudent();
// 3. 使用Gson解析:將JSON數(shù)據(jù)轉(zhuǎn)為單個(gè)類實(shí)體
String json = "{\"id\":1,\"name\":\"小明\",\"sex\":\"男\(zhòng)",\"age\":18,\"height\":175}";
student = gson.fromJson(json,Student.class);
// 解析:JavaBean對(duì)象 = gson.fromJson(son,javaBean類類名.class);
// 4. 調(diào)用student方法展示解析的數(shù)據(jù)
student.show();
// 5. 將Java集合轉(zhuǎn)換為json
String json2 = gson.toJson(List);
System.out.println(json2);
}
}
3.3 Jackson解析
- 解析原理:基于事件驅(qū)動(dòng)
- 解析過程:
- 類似
GSON
,先創(chuàng)建1個(gè)對(duì)應(yīng)于JSON
數(shù)據(jù)的JavaBean
類,再通過簡(jiǎn)單操作即可解析 - 與
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ù)所有解析出來,無(wú)法按需解析
- 類似
但Jackson的解析速度、效率都 高于 GSON
- 具體使用
步驟1:建立Json
數(shù)據(jù)對(duì)應(yīng)的javaBean(規(guī)則同GSON)
// 創(chuàng)建需解析的JSON數(shù)據(jù):student.json
// 將該文件放入到本地assets文件夾里
{"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"
}
// JavaBean類
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)行解析
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ObjectMapper objectMapper = new ObjectMapper();
try {
// 1. //從assets獲取json文件
InputStreamReader isr = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("assets/" + "student.json"),"utf-8");
BufferedReader bfr = new BufferedReader(isr);
String line;
StringBuilder stringBuilder = new StringBuilder();
while ((line = bfr.readLine())!=null){
stringBuilder.append(line);
}
// 2. 將JSON數(shù)據(jù)轉(zhuǎn)化為字符串
System.out.println(stringBuilder.toString());
System.out.println(tes.tostring());
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 解析方式對(duì)比
示意圖
5. 與XML解析對(duì)比
- 對(duì)于 同樣作為主流的數(shù)據(jù)交換格式
XML
來說,二者對(duì)比如下:
示意圖 - 總的來說,相比于
XML
,JSON
大小更小、解析方法更簡(jiǎn)單、解析速度更快。所以,JSON
一定是你在數(shù)據(jù)交換格式選型中的首選
6. 總結(jié)
- 本文全面介紹了現(xiàn)今主流的數(shù)據(jù)傳輸格式:
JSON
- 關(guān)于另外1種主流的數(shù)據(jù)傳輸格式
XML
,具體請(qǐng)看:Carson帶你學(xué)序列化:深入分析XML多種解析方式(DOM、SAX、PULL)
歡迎關(guān)注Carson_Ho的簡(jiǎn)書
不定期分享關(guān)于安卓開發(fā)的干貨,追求短、平、快,但卻不缺深度。