手动解析json的惨痛经历

想必安卓开发这边一般都是通过json来传输数据,然后通过gson 或者 fastjson来解析json串,通常是没啥问题的。。。然而还有特殊情况,下面就来讲讲特殊情况吧。

 "datalist": [
            {
                "id": 1,
                "sortindex": "111",
                "type": "cartoon",
                "details": {
                    "id": 1,
                    "title": "xxxx",
                    "summary": "xxxx",
                    "imageurl": "xxxx",
                    "url": "http://m.kk-me.com/article/1.html"
                }
            },
            {
                "id": 1,
                "sortindex": "111",
                "type": "article",
                "details": {
                    "id": 1,
                    "title": "xxxx",
                    "imageurl": [
                        "xxx",
                        "xxxx"
                    ],
                    "url": "http://m.kk-me.com/article/1.html",
                    "needpay": 1
                }
            }
]

请注意里面的type字段,这个是根据业务场景来的,就是一个列表里面有
cartoon类型的也有article类型的。里面有一个关键的字段imageurl,没错就是他,在上一个类型的时候是字符串类型 但是下一个类型的时候就成了数组类型。

看到这里你也许会想让后台改改字段不就行了,然并卵,后台说基于扩展1张图片的时候就是字符串,展示3张图片的时候就是数组了,合情合理不修改。。。无奈啊,前端的悲哀,人家这样反得只能这样解析了。

因为用习惯了三方解析,自然不愿意手动解析啊,人都是有惰性的嘛,再说项目比较急,开始准备解析方案:

  1. 在gson里面的bean里面设置一个通用列表条目的bean,将imageurl设为Object类型,到时候再强制转换。
    事实证明这个方案不可行,三方解析的时候必须明确定义字段的确切数据类型

2.因为在列表里面只有imageurl这个字段有可能为数组类型,那就先拿到数据返回的字符转进行解析,先将"[ ]"这两个字符替换为 "" 将其变为字符串类型,到时候再通过","符号进行切割在取值,总之就是不愿手动解析
这个方案一开始感觉不错,但是操作下来就出问题了。首先,忽略了datalist 这个字段跟的数组类型,要替换的时候也会把这个符号给替换掉,要找需要修改的数组符号不好判定 。 其次,这个列表是首页返回的数据,json串挺大的,遍历替换的话对性能也有影响。最后,不易扩展,有可能以后别的添加的字段也是数组的类型,到时候你还得再去判定一遍

3.最后考量再三只能用手动解析了。。。。

先手动创建一个通用的bean对象,解析的时候将数据存入

public class DatalistBean {   
public long id;    
public String sortindex;    
public String type;    
public DynamicItemBean details;
public class DynamicItemBean {   
  public long id;    
  public String title;    
  public String imageurl;   
  public String url;    
  public ArrayList<String> imagearray;   //此字段代表imageurl为数组情形
    ....其他的字段此处省略
}
}

然后进行解析:

try {
//obj为上文解析出来的JSONObject对象,这边就不再展示了
JSONArray datalist_array = obj.getJSONArray("datalist");
for (int i = 0; i < datalist_array.length(); i++) {    
JSONObject slider_obj = datalist_array.getJSONObject(i);        
DatalistBean datalistBean = new DatalistBean();   
 datalistBean.id = slider_obj.getLong("id");    
  datalistBean.sortindex = slider_obj.getString("sortindex");               
  datalistBean.type = slider_obj.getString("type");   
 JSONObject details = slider_obj.getJSONObject("details");          
 DynamicItemBean dynamicItemBean = new DynamicItemBean();          
  dynamicItemBean.id = details.getLong("id");  
 dynamicItemBean.title = details.getString("title");     
dynamicItemBean.imagearray = new ArrayList<String>();  
  switch (datalistBean.type) {        
    case "article":                        
    dynamicItemBean.url = details.getString("url");           
   JSONArray imageurl_array = details.getJSONArray("imageurl");                
    if (imageurl_array.length() != 0) {               
    for (int b = 0; b < imageurl_array.length(); b++) {                    
    dynamicItemBean.imagearray.add(imageurl_array.getString(b));                    
    }          
   }         
   break;
case "cartoon":    
  dynamicItemBean.imageurl = details.getString("imageurl");      
  dynamicItemBean.needpay = details.getInt("needpay");        
  dynamicItemBean.url = details.getString("url");    
  break;
   }    
  datalistBean.details = dynamicItemBean;        
  dynamic_list.add(datalistBean);//dynamic_list为所要填充的集合
}
} catch (JSONException e) {    
  e.printStackTrace();
}

这里要特别注意一点,设置imagearray为集合类型的时候,赋值的时候
需要添加如下代码进行初始化,不然的话取值不到:

dynamicItemBean.imagearray = new ArrayList<String>();

还有有可能后台返回数据datalist为null的情况,这样的话前面就需要加个判断,是否为null,为null的话就不解析了:

if(obj.isNull("datalist")){ 
 return;
}

三方的运用越来越便捷,但是原先基础的解析也忘的都差不多了。其实手动解析也没有想象的那么难,一切反动派都是纸老虎啊。
哈哈,与诸君共勉

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容