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 '\t': case ' ': case '\n': case '\r': 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); } }

相关文章

文章浏览阅读2.4k次。最近要优化cesium里的热力图效果,浏览...
文章浏览阅读1.2w次,点赞3次,收藏19次。在 Python中读取 j...
文章浏览阅读1.4k次。首字母缩略词 API 代表应用程序编程接口...
文章浏览阅读802次,点赞10次,收藏10次。解决一个JSON反序列...
文章浏览阅读882次。Unity Json和Xml的序列化和反序列化_uni...