• Android 解析未知格式的json数据


    1、递归一
    有的时候我们需要解析未知的json。或者说是动态的json。那么我们并不知道key具体是多少,或者说key不是固定的。这时候就需要解析动态key的方法。

    这个方法是我在实现解析前台传入的json时所需要的。因为每个界面的前台传的是json是不固定的。如果真对每一个页面所传的数据都单独进行一次解析,那么太麻烦了。所以需要一个通用的解析方式。将其解析到map中。那么只需要调用该方法,就能获取到前台所传json对于的map。

    在网上搜了一会,找不到我想要的方法,即不和我心意,代码又不给全。所以自己测试了一个简单的代码。我是使用递归实现的,代码简单。就不一一讲解了,如果还有不清楚的,请留言。

     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     }


    效果如下:

    2、递归二
    上面的递归方式只支持没有包含数组格式的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数组,需要继续解析。
    要实现这两个格式的兼容。下面的代码能够实现:

     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串。

    执行代码

     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 }


    效果如下:


    注意:上图中 的name我分为name1,name2,name3。上图只有一个age。因为key重名了,所以放入map中自然会被覆盖掉。如果三个name一样,最后只能得到一个name一个age.
    **

    3、递归三
    **
    递归二的方式可以实现大部分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 

  • 相关阅读:
    基于antd封装一个高可用form组件 减少cv代码导致的bug
    写一个umi插件 自动生成代码 解放cv的双手
    jquery.validate的一个bug
    ef6+mysql的bug
    angularJS使用ocLazyLoad实现js延迟加载
    postgresql,postgis,geoserver 发布地图服务,并用.net mvc openlayers3进行显示
    EF框架操作postgresql,实现WKT类型坐标的插入,查询,以及判断是否相交
    jquery validate 之多tab页同时校验问题
    js去除空格12种方法
    个人工具清单
  • 原文地址:https://www.cnblogs.com/Sharley/p/10470375.html
Copyright © 2020-2023  润新知