Android 解析未知格式的json數據

一、遞歸一
有的時候咱們須要解析未知的json。或者說是動態的json。那麼咱們並不知道key具體是多少,或者說key不是固定的。這時候就須要解析動態key的方法。java

這個方法是我在實現解析前臺傳入的json時所須要的。由於每一個界面的前臺傳的是json是不固定的。若是真對每個頁面所傳的數據都單獨進行一次解析,那麼太麻煩了。因此須要一個通用的解析方式。將其解析到map中。那麼只須要調用該方法,就能獲取到前臺所傳json對於的map。正則表達式

在網上搜了一會,找不到我想要的方法,即不和我心意,代碼又不給全。因此本身測試了一個簡單的代碼。我是使用遞歸實現的,代碼簡單。就不一一講解了,若是還有不清楚的,請留言。json

 1 import java.util.HashMap;
 2 import java.util.Iterator;
 3 import java.util.Map;
 4 import java.util.Set;
 5 
 6 import net.sf.json.JSONObject;
 7 
 8     public class JsonTest {
 9         public static void main(String[] args) {
10 //測試字符串
11             String test = "{a:1,b:2,c:3,d:{q:4,w:5,e:6,y:{o:7,p:8}}}";
12             Map res = new HashMap();
13 //遞歸遍歷解析方法
14             iteraJson(test,res);
15 //解析獲得最終map後,遍歷該map輸出值
16             Set keySet = res.keySet();
17             Iterator iterator = keySet.iterator();
18             while(iterator.hasNext()){
19                 String key = iterator.next().toString();
20                 Object val = res.get(key);
21                 System.out.println(key+":"+val.toString());
22             }
23         }
24         //遞歸遍歷解析方法
25         public static boolean iteraJson(String str,Map res){
26 //由於json串中不必定有逗號,可是必定有:號,因此這裏判斷沒有則已經value了
27             if(str.toString().indexOf(":") == -1){
28                 return true;
29             }
30             JSONObject fromObject = JSONObject.fromObject(str);
31             Iterator keys = fromObject.keys();
32             while(keys.hasNext()){
33                 String key = keys.next().toString();
34                 Object value = fromObject.get(key);
35                 if(iteraJson(value.toString(),res)){
36                     res.put(key, value);
37                 }
38             }
39             return false;
40         }
41     }


效果以下: 數組

 

二、遞歸二
上面的遞歸方式只支持沒有包含數組格式的json字符串。例如:測試

String test = "{a:1,b:[1,2,3],c:3,d:{q:4,w:5,e:6,y:{o:7,p:8}},arry:[{name1:'joker',age:30},{name2:'dd',age:20},{name3:'bb',age:10}]}";

 

b:[1,2,3] 這個數組是正規數組,不是json數組,不須要解析。
arry:[{name1:’joker’,age:30},{name2:’dd’,age:20},{name3:’bb’,age:10}]。這個是json數組,須要繼續解析。
要實現這兩個格式的兼容。下面的代碼可以實現:spa

 1     public static boolean iteraJsonOrArray(String source,Map map){
 2         if(source.indexOf(":") == -1){
 3             return true;
 4         }
 5         JSONObject fromObject = JSONObject.fromObject(source);
 6         Iterator keys = fromObject.keys();
 7         while(keys.hasNext()){
 8             String key = keys.next().toString();
 9             Object value = fromObject.get(key);
10             String val = value.toString();
11             if(val.indexOf("[{") == -1){
12                 //說明不存在數組json即格式爲:"[{" 開頭的數據。能夠容許是[10,11,12]的非json數組
13                 if(val.indexOf(":") == -1){
14                     map.put(key, val);
15                 }else{
16                     iteraJson(val,map);
17                 }
18             }else if(val.indexOf("[{") != -1){
19                 //說明存在數組json即格式爲:[{開頭的json數組
20                 if(val.indexOf("[{") == 0){
21                     //說明當前value就是一個json數組
22                     //去除[括號
23                     String jsons = val.substring(1, val.lastIndexOf("]"));//獲得數據格式爲:{...},{...},{...}
24                     //把上面獲得jsons分割成數組
25                     //由於數據格式爲{name:joker,age:20},{...},{...},因此不能用逗號分割。不然會變"{name:joker" "age:20}"
26                     //使用正則表達式把},{替換成}|{
27                     jsons = jsons.replaceAll("\\}\\s?,\\s?\\{", "}|{");
28                     String[] split = jsons.split("\\|");
29                     for(int i = 0; i < split.length;i++){
30                         iteraJsonOrArray(split[i],map);//符合當前遞歸條件
31                     }
32 
33                 }else{
34                     //說明value多是一個json,這個json中任然包含數組。例如:{inner:[{a:1,b:2,c:3}]}
35                     iteraJsonOrArray(val,map);//符合當前遞歸條件
36                 }
37             }
38 
39         }
40 
41         return false;
42     }

 

 

把 iteraJsonOrArray 方法寫到遞歸一中的代碼裏。由於這個方法裏調用了遞歸一中的iteraJson來解析沒包含任何數組類型的json串。.net

執行代碼3d

 1 String test = "{a:1,b:[1,2,3],c:3,d:{q:4,w:5,e:6,y:{o:7,p:8}},arry:[{name1:'joker',age:30},{name2:'dd',age:20},{name3:'bb',age:10}]}";
 2 Map res = new HashMap();
 3 iteraJsonOrArray(test,res);
 4 Set keySet = res.keySet();
 5 Iterator iterator = keySet.iterator();
 6 while(iterator.hasNext()){
 7    String key = iterator.next().toString();
 8    Object val = res.get(key);
 9    System.out.println(key+":"+val.toString());
10 }

 


效果以下: code

 


注意:上圖中 的name我分爲name1,name2,name3。上圖只有一個age。由於key重名了,因此放入map中天然會被覆蓋掉。若是三個name同樣,最後只能獲得一個name一個age.
**blog

三、遞歸三
**
遞歸二的方式能夠實現大部分json格式。可是遇到key相同的json就很差保存數據。
好比:{arry:[{name:joker,age:15},{name:jake,age:20},{name:mari,age:25}]};這種格式用遞歸二的話,放入map中,最後只獲得name:mari 和 age:25。

因此咱們須要把全部的值都保存起來,那麼就不是放入map中,而是list中了。
以下圖,在遞歸二中建立臨時tempmap和list。而後把list添加到最終map中。

 


輸出結果爲:

 


這樣就能夠接受前臺傳到後臺的json數據。這個json數據能夠包含表單的值和表格的值一塊兒。
--------------------- 

轉自:https://blog.csdn.net/Esc_Tab_End/article/details/80210659 

相關文章
相關標籤/搜索