什么是JSON
官網的解釋是JSON (JavaScript Object Notation) is a lightweight data-interchange format 。
JSON的格式
鍵值對的集合 {k:v}
值得有序列表 [1,2]
什么是JSON-java
JSON官網提供的java語言處理json數據的小框架。
閱讀該源碼的目的
1、學習解析類工具的原理
2、鍛煉讀代碼的能力
解析JSON的原理
1、JSON-java最重要的類有三個。
JSONObject : 包裝一個map。 用來表示一個{k:v,k2:v2,k3:[1,2]}形式的json數據
JSONArray :包裝一個ArrayList。用來表示一個[1,2,{k:v}]形式的json數據
JSONTokener:包裝一個Reader。用來存儲、讀取、操作一個表示JSON數據的字符串
2、原理
1、JSONObject和JSONArray都可以用一個JSONTokener作為構造參數去實例化。
2、解析時可能會產生多個JSONObject或者JSONArray。但是他們都是操作同一個JSONTokener。
3、JSONObject和JSONArray可以分別通過JSONTokener提供的方法解析出對方。可以實現嵌套。
例子
new JSONObject("{k:v,k2:v2,k3:[1,{k4:V4}]}");
解析出{
解析出k和v存入map
解析出k2和v2存入map
解析出k3 然后發現一個數組的左標記[
new JSONArray 開始解析[1,{k4:V4}]}
解析出[
解析出1 放入list
解析出json對象的左標記{
new JSONObject 開始解析 {k4:V4}]}
解析出k4和v4放入map
發現}一個JSONObject解析結束
解析出 {k4:V4} 放入list。
發現 ] 一個JSONArray解析結束
解析出[1,{k4:V4}] 和k3 一起放入map (第一個JSONObject)。
解析出}
全部解析結束。
3、實現
JSONTokener 重要的Field(數據)和Method(操作)
private int character; // 當前行字符的index
private boolean eof; // 標記讀到尾部
private int index; // 所有行字符的index
private int line; // 行數
private char previous; // 緩存
private Reader reader; // JSON數據
private boolean usePrevious; // 使用緩存標志
public char next() throws JSONException
從reader或者緩存(previous)里讀取一個char,並且設置和統計重要的Field。
public void back() throws JSONException
將各種統計的field恢復到上一個的狀態。並且把userPrevious設置成true(即下次使用next()時從緩存里拿一個char)
next和back使的JSONTokener有了一個向前探測一個字符的能力。
public char nextClean() throws JSONException
讀取一個可見字符串或者一個結束符\0。(看了人家的代碼才意識到空格之前的都是不可見字符)
public String nextString(String quote) throws JSONException
讀一個封閉的引用符內的字符串。(這里會做一個轉義處理)
轉義處理解讀
如果碰到\ 作轉義處理:轉義處理:往后讀一位
1、如果后面的是b t n f r 往buff里添加相應的轉義字符
2、如果后面的是u 則next(4) 轉成 16進制Int 轉成char 添加到buff
3、如果后面的是u 則next(4) 轉成 16進制Int 轉成char 添加到buff
4、后面如果是‘ “ \ / 直接把該字符添加到buff
5、其他情況拋出Illegal escape.
public Object nextValue() throws JSONException
這個方法很重要! 讀取下一個封閉引用符號括起來的值,或者各種基本的數據類型,或者一個JSONObject和JSONArray。(嵌套的關鍵)
public Object nextValue() throws JSONException {
char c = nextClean(); // 探測
String string;
switch (c) {
case '"':
case '\'':
return nextString(c);
case '{':
back(); // 探測到回退
return new JSONObject(this);
case '[':
back();
return new JSONArray(this);
}
StringBuffer sb = new StringBuffer();
while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
sb.append(c);
c = next();
}
back();
string = sb.toString().trim();
if (string.equals("")) {
throw syntaxError("Missing value");
}
return JSONObject.stringToValue(string);
}
JSONArray的構造器(注意JSON-java支持非正規的JSON格式可以用多種符號分隔數據)
public JSONArray(JSONTokener x) throws JSONException {
this();
if (x.nextClean() != '[') {
throw x.syntaxError("A JSONArray text must start with '['");
}
if (x.nextClean() != ']') {
x.back();
for (;;) {
if (x.nextClean() == ',') {
x.back();
this.myArrayList.add(JSONObject.NULL);
} else {
x.back();
this.myArrayList.add(x.nextValue());
}
switch (x.nextClean()) {
case ';':
case ',':
if (x.nextClean() == ']') {
return;
}
x.back();
break;
case ']':
return;
default:
throw x.syntaxError("Expected a ',' or ']'");
}
}
}
}
JSONObject的構造器(注意JSON-java支持非正規的JSON格式可以用多種符分隔數據)
public JSONObject(JSONTokener x) throws JSONException {
this();
char c;
String key;
if (x.nextClean() != '{') {
throw x.syntaxError("A JSONObject text must begin with '{'");
}
for (;;) {
c = x.nextClean();
switch (c) {
case 0:
throw x.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
default:
x.back();
key = x.nextValue().toString();
}
// The key is followed by ':'. We will also tolerate '=' or '=>'.
c = x.nextClean();
if (c == '=') {
if (x.next() != '>') {
x.back();
}
} else if (c != ':') {
throw x.syntaxError("Expected a ':' after a key");
}
putOnce(key, x.nextValue());
// Pairs are separated by ','. We will also tolerate ';'.
switch (x.nextClean()) {
case ';':
case ',':
if (x.nextClean() == '}') {
return;
}
x.back();
break;
case '}':
return;
default:
throw x.syntaxError("Expected a ',' or '}'");
}
}
}
