JSONObject解析json字符串实现
JSONObject解析json字符串实现
1.题目:从最简单的使用开始
{
"name1": "休闲",
"name2": "棋牌",
"name3": "益智",
"url1": "image/category_game_0.jpg",
"url2": "image/category_game_1.jpg",
"url3": "image/category_game_2.jpg"
},
2.研究JSONObject的实现:既如何解析上述json字符串
// 获取title的节点数据
// Creates a new {@code JSONObject} with name/value mappings from the next object in the tokener.
JsonObject jsonObject = new JSONObject(jsonStr); // jsonStr是上述字符串
titleBean.title = jsonObject.getString("title");
// JSONObject实现如下:
// 复杂保存键值对
public JSONObject(String json) throws JSONException {
this(new JSONTokener(json));
}
// 负责具体解析
public JSONTokener(String in) {// Token:代币;象征;记号
this.in = in;
}
public JSONObject(JSONTokener readFrom) throws JSONException {
/*
* Getting the parser to populate this could get tricky. Instead, just
* parse to temporary JSONObject and then steal the data from that.
*/
Object object = readFrom.nextValue();
if (object instanceof JSONObject) {
this.nameValuePairs = ((JSONObject) object).nameValuePairs;
} else {
throw JSON.typeMismatch(object, "JSONObject");
}
}
public JSONObject() {// 使用键值对保存节点序列
nameValuePairs = new HashMap<String, Object>();
}
/**
* Returns the next value from the input.
*
* @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
* Integer, Long, Double or {@link JSONObject#NULL}.
* @throws JSONException if the input is malformed.
*/
public Object nextValue() throws JSONException {
int c = nextCleanInternal();
switch (c) {
case -1:
throw syntaxError("End of input");
case "{": // 一开始就解析Object--解析的核心代码在这里
return readObject();
case "[":
return readArray();
case """:
return nextString((char) c);
...
}
}
/* 读取一个字符 */
private int nextCleanInternal() throws JSONException {
while (pos < in.length()) {
int c = in.charAt(pos++); // 此时pos从0变为1
switch (c) {
case " ":
case " ":
case " ":
case " ":
continue;
...
default:
return c;
}
}
return -1; // 读到文件末尾
}
/**
* 核心代码:读取一个Object
* Reads a sequence of key/value pairs and the trailing closing brace "}" of
* an object. The opening brace "{" should have already been read.
*/
private JSONObject readObject() throws JSONException {
JSONObject result = new JSONObject(); // new出一个键值对
/* Peek to see if this is the empty object. */
int first = nextCleanInternal(); // pos由1变为2
if (first == "}") {
return result;
} else if (first != -1) { // pos由2变为1
pos--;
}
while (true) {
// 走一次解析出一个键值对--->"name1": "休闲",
// 获得"name1"
Object name = nextValue(); // 获取name获取""或""之间的数据
/*
* Expect the name/value separator to be either a colon ":", an
* equals sign "=", or an arrow "=>". The last two are bogus but we
* include them because that"s what the original implementation did.
*/
int separator = nextCleanInternal();
if (separator != ":" && separator != "=") {
throw syntaxError("Expected ":" after " + name);
}
if (pos < in.length() && in.charAt(pos) == ">") {// 跳过":"
pos++;
}
// 获得"休闲",并加入到键值对中
result.put((String) name, nextValue());// 设置Map键值对
switch (nextCleanInternal()) { // 跳过","
case "}":
return result;
case ";":
case ",":
continue;
default:
throw syntaxError("Unterminated object");
}
}
}
/*
获取""或""之间的数据
*/
public String nextString(char quote) throws JSONException {
/*
* For strings that are free of escape sequences, we can just extract
* the result as a substring of the input. But if we encounter an escape
* sequence, we need to use a StringBuilder to compose the result.
*/
StringBuilder builder = null;
/* the index of the first character not yet appended to the builder. */
int start = pos;
while (pos < in.length()) {
int c = in.charAt(pos++);
if (c == quote) { // 走该分支--提取出两个:""之间的数据
if (builder == null) {
// a new string avoids leaking memory
return new String(in.substring(start, pos - 1));
} else {
builder.append(in, start, pos - 1);
return builder.toString();
}
}
...
}
}
总结:
1.解析实现主要由两个类实现:JSONObject和JSONTokener
其中:JSONObject复杂保存解析出来的键值对的map序列
JSONTokener负责底层具体解析工作(解析出对象,数组,简单键值对...)
--------------------------------------------------------------------------------------
3.复杂解析:(解析过程是递归进行的)
原始数据:
[{title:"游戏",infos:[{url1:"image/category_game_0.jpg",url2:"image/category_game_1.jpg",url3:"image/category_game_2.jpg",name1:"休闲",name2:"棋牌",name3:"益智"},{url1:"image/category_game_3.jpg",url2:"image/category_game_4.jpg",url3:"image/category_game_5.jpg",name1:"射击",name2:"体育",name3:"儿童"},{url1:"image/category_game_6.jpg",url2:"image/category_game_7.jpg",url3:"image/category_game_8.jpg",name1:"网游",name2:"角色",name3:"策略"},{url1:"image/category_game_9.jpg",url2:"image/category_game_10.jpg",url3:"",name1:"经营",name2:"竞速",name3:""}]},{title:"应用",infos:[{url1:"image/category_app_0.jpg",url2:"image/category_app_1.jpg",url3:"image/category_app_2.jpg",name1:"浏览器",name2:"输入法",name3:"健康"},{url1:"image/category_app_3.jpg",url2:"image/category_app_4.jpg",url3:"image/category_app_5.jpg",name1:"效率",name2:"教育",name3:"理财"},{url1:"image/category_app_6.jpg",url2:"image/category_app_7.jpg",url3:"image/category_app_8.jpg",name1:"阅读",name2:"个性化",name3:"购物"},{url1:"image/category_app_9.jpg",url2:"image/category_app_10.jpg",url3:"image/category_app_11.jpg",name1:"资讯",name2:"生活",name3:"工具"},{url1:"image/category_app_12.jpg",url2:"image/category_app_13.jpg",url3:"image/category_app_14.jpg",name1:"出行",name2:"通讯",name3:"拍照"},{url1:"image/category_app_15.jpg",url2:"image/category_app_16.jpg",url3:"image/category_app_17.jpg",name1:"社交",name2:"影音",name3:"安全"}]}]
解析过程:
// 获取根节点的对象
JSONArray array = new JSONArray(json);
// 遍历节点
for (int i = 0; i < array.length(); i++)
{
JSONObject jsonObject = array.getJSONObject(i);
CategoryBean titleBean = new CategoryBean();
titleBean.isTitle = true;
// 获取title的节点数据
titleBean.title = jsonObject.getString("title");
// 将 bean添加到集合
if (list == null)
{
list = new ArrayList<CategoryBean>();
}
list.add(titleBean);
// 获取infos节点
JSONArray infosArray = jsonObject.getJSONArray("infos");
// 遍历infosArray集合
for (int j = 0; j < infosArray.length(); j++)
{
JSONObject infoObject = infosArray.getJSONObject(j);
CategoryBean infoBean = new CategoryBean();
infoBean.isTitle = false;
infoBean.name1 = infoObject.getString("name1");
infoBean.name2 = infoObject.getString("name2");
infoBean.name3 = infoObject.getString("name3");
infoBean.url1 = infoObject.getString("url1");
infoBean.url2 = infoObject.getString("url2");
infoBean.url3 = infoObject.getString("url3");
if (list == null)
{
list = new ArrayList<CategoryBean>();
}
list.add(infoBean);
}
}
1.题目:从最简单的使用开始
{
"name1": "休闲",
"name2": "棋牌",
"name3": "益智",
"url1": "image/category_game_0.jpg",
"url2": "image/category_game_1.jpg",
"url3": "image/category_game_2.jpg"
},
2.研究JSONObject的实现:既如何解析上述json字符串
// 获取title的节点数据
// Creates a new {@code JSONObject} with name/value mappings from the next object in the tokener.
JsonObject jsonObject = new JSONObject(jsonStr); // jsonStr是上述字符串
titleBean.title = jsonObject.getString("title");
// JSONObject实现如下:
// 复杂保存键值对
public JSONObject(String json) throws JSONException {
this(new JSONTokener(json));
}
// 负责具体解析
public JSONTokener(String in) {// Token:代币;象征;记号
this.in = in;
}
public JSONObject(JSONTokener readFrom) throws JSONException {
/*
* Getting the parser to populate this could get tricky. Instead, just
* parse to temporary JSONObject and then steal the data from that.
*/
Object object = readFrom.nextValue();
if (object instanceof JSONObject) {
this.nameValuePairs = ((JSONObject) object).nameValuePairs;
} else {
throw JSON.typeMismatch(object, "JSONObject");
}
}
public JSONObject() {// 使用键值对保存节点序列
nameValuePairs = new HashMap<String, Object>();
}
/**
* Returns the next value from the input.
*
* @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
* Integer, Long, Double or {@link JSONObject#NULL}.
* @throws JSONException if the input is malformed.
*/
public Object nextValue() throws JSONException {
int c = nextCleanInternal();
switch (c) {
case -1:
throw syntaxError("End of input");
case "{": // 一开始就解析Object--解析的核心代码在这里
return readObject();
case "[":
return readArray();
case """:
return nextString((char) c);
...
}
}
/* 读取一个字符 */
private int nextCleanInternal() throws JSONException {
while (pos < in.length()) {
int c = in.charAt(pos++); // 此时pos从0变为1
switch (c) {
case " ":
case " ":
case " ":
case " ":
continue;
...
default:
return c;
}
}
return -1; // 读到文件末尾
}
/**
* 核心代码:读取一个Object
* Reads a sequence of key/value pairs and the trailing closing brace "}" of
* an object. The opening brace "{" should have already been read.
*/
private JSONObject readObject() throws JSONException {
JSONObject result = new JSONObject(); // new出一个键值对
/* Peek to see if this is the empty object. */
int first = nextCleanInternal(); // pos由1变为2
if (first == "}") {
return result;
} else if (first != -1) { // pos由2变为1
pos--;
}
while (true) {
// 走一次解析出一个键值对--->"name1": "休闲",
// 获得"name1"
Object name = nextValue(); // 获取name获取""或""之间的数据
/*
* Expect the name/value separator to be either a colon ":", an
* equals sign "=", or an arrow "=>". The last two are bogus but we
* include them because that"s what the original implementation did.
*/
int separator = nextCleanInternal();
if (separator != ":" && separator != "=") {
throw syntaxError("Expected ":" after " + name);
}
if (pos < in.length() && in.charAt(pos) == ">") {// 跳过":"
pos++;
}
// 获得"休闲",并加入到键值对中
result.put((String) name, nextValue());// 设置Map键值对
switch (nextCleanInternal()) { // 跳过","
case "}":
return result;
case ";":
case ",":
continue;
default:
throw syntaxError("Unterminated object");
}
}
}
/*
获取""或""之间的数据
*/
public String nextString(char quote) throws JSONException {
/*
* For strings that are free of escape sequences, we can just extract
* the result as a substring of the input. But if we encounter an escape
* sequence, we need to use a StringBuilder to compose the result.
*/
StringBuilder builder = null;
/* the index of the first character not yet appended to the builder. */
int start = pos;
while (pos < in.length()) {
int c = in.charAt(pos++);
if (c == quote) { // 走该分支--提取出两个:""之间的数据
if (builder == null) {
// a new string avoids leaking memory
return new String(in.substring(start, pos - 1));
} else {
builder.append(in, start, pos - 1);
return builder.toString();
}
}
...
}
}
总结:
1.解析实现主要由两个类实现:JSONObject和JSONTokener
其中:JSONObject复杂保存解析出来的键值对的map序列
JSONTokener负责底层具体解析工作(解析出对象,数组,简单键值对...)
--------------------------------------------------------------------------------------
3.复杂解析:(解析过程是递归进行的)
原始数据:
[{title:"游戏",infos:[{url1:"image/category_game_0.jpg",url2:"image/category_game_1.jpg",url3:"image/category_game_2.jpg",name1:"休闲",name2:"棋牌",name3:"益智"},{url1:"image/category_game_3.jpg",url2:"image/category_game_4.jpg",url3:"image/category_game_5.jpg",name1:"射击",name2:"体育",name3:"儿童"},{url1:"image/category_game_6.jpg",url2:"image/category_game_7.jpg",url3:"image/category_game_8.jpg",name1:"网游",name2:"角色",name3:"策略"},{url1:"image/category_game_9.jpg",url2:"image/category_game_10.jpg",url3:"",name1:"经营",name2:"竞速",name3:""}]},{title:"应用",infos:[{url1:"image/category_app_0.jpg",url2:"image/category_app_1.jpg",url3:"image/category_app_2.jpg",name1:"浏览器",name2:"输入法",name3:"健康"},{url1:"image/category_app_3.jpg",url2:"image/category_app_4.jpg",url3:"image/category_app_5.jpg",name1:"效率",name2:"教育",name3:"理财"},{url1:"image/category_app_6.jpg",url2:"image/category_app_7.jpg",url3:"image/category_app_8.jpg",name1:"阅读",name2:"个性化",name3:"购物"},{url1:"image/category_app_9.jpg",url2:"image/category_app_10.jpg",url3:"image/category_app_11.jpg",name1:"资讯",name2:"生活",name3:"工具"},{url1:"image/category_app_12.jpg",url2:"image/category_app_13.jpg",url3:"image/category_app_14.jpg",name1:"出行",name2:"通讯",name3:"拍照"},{url1:"image/category_app_15.jpg",url2:"image/category_app_16.jpg",url3:"image/category_app_17.jpg",name1:"社交",name2:"影音",name3:"安全"}]}]
解析过程:
// 获取根节点的对象
JSONArray array = new JSONArray(json);
// 遍历节点
for (int i = 0; i < array.length(); i++)
{
JSONObject jsonObject = array.getJSONObject(i);
CategoryBean titleBean = new CategoryBean();
titleBean.isTitle = true;
// 获取title的节点数据
titleBean.title = jsonObject.getString("title");
// 将 bean添加到集合
if (list == null)
{
list = new ArrayList<CategoryBean>();
}
list.add(titleBean);
// 获取infos节点
JSONArray infosArray = jsonObject.getJSONArray("infos");
// 遍历infosArray集合
for (int j = 0; j < infosArray.length(); j++)
{
JSONObject infoObject = infosArray.getJSONObject(j);
CategoryBean infoBean = new CategoryBean();
infoBean.isTitle = false;
infoBean.name1 = infoObject.getString("name1");
infoBean.name2 = infoObject.getString("name2");
infoBean.name3 = infoObject.getString("name3");
infoBean.url1 = infoObject.getString("url1");
infoBean.url2 = infoObject.getString("url2");
infoBean.url3 = infoObject.getString("url3");
if (list == null)
{
list = new ArrayList<CategoryBean>();
}
list.add(infoBean);
}
}
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: java 创建json对象
- 下一篇: Java解析Json字符串--单个实体