美文网首页Android developing tips1-Android开发知识Android知识
项目需求讨论-后台返回的特殊JSON处理

项目需求讨论-后台返回的特殊JSON处理

作者: 青蛙要fly | 来源:发表于2017-02-05 21:07 被阅读1802次

    在实际开发中,现在安卓端和后台之间的数据交互,一般都是用JSON来传递数据信息。JSON大家一般都比较熟悉。我这边就以实际项目中的后台传过来的情况和大家分析下及如何处理。

    比如后台返回一个交易查询:

    我们看到这个列表本身要按月份来进行分类。然后月份里面再是具体的一项项记录。
    这里我们分二种后台传给你的JSON格式情况讲解下:(重点是第二种情况)

    普通格式

    一般来说后台会根据这个需求传递相关JSON:
    比如后台一般这么发给你:

    {
        "success": true,
        "msg": "用户查询订单成功",
        "obj": [
            {
                "month": {
                    "date": "09月",
                    "list": [
                        {
                            "companyName": "宁波心科技有限公司",
                            "createDate": "2016.09.14 17:35:45",
                            "money": "5000",
                            "type": "2"
                        },
                        {
                            "companyName": "湖南省林森科技有限公司",
                            "createDate": "2016.09.10 17:35:45",
                            "money": "5900",
                            "type": "2"
                        }
                    ]
                }
            },
            {
                "month": {
                    "date": "11月",
                    "list": [
                        {
                            "companyName": "杭州心科技有限公司",
                            "createDate": "2016.11.14 17:35:45",
                            "money": "-200",
                            "type": "1"
                        },
                        {
                            "companyName": "湖南省林森科技有限公司",
                            "createDate": "2016.11.10 17:35:45",
                            "money": "-5900",
                            "type": "1"
                        }
                    ]
                }
            }
        ]
    }
    

    OK,这种情况很简单。我们只要建立一个对象类,然后通过网络获取到JSON的时候进行转换,然后转成我们的对象类即可。

    public class Bean {
    
        private boolean success;
        private String msg;
        private List<ObjBean> obj;
    
        public boolean isSuccess() {
            return success;
        }
    
        public void setSuccess(boolean success) {
            this.success = success;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public List<ObjBean> getObj() {
            return obj;
        }
    
        public void setObj(List<ObjBean> obj) {
            this.obj = obj;
        }
    
        public static class ObjBean {
            /**
             * month : {"date":"09月","list":[{"companyName":"宁波心科技有限公司","createDate":"2016.09.14 17:35:45","money":"5000","type":"2"},{"companyName":"湖南省林森科技有限公司","createDate":"2016.09.10 17:35:45","money":"5900","type":"2"}]}
             */
    
            private MonthBean month;
    
            public MonthBean getMonth() {
                return month;
            }
    
            public void setMonth(MonthBean month) {
                this.month = month;
            }
    
            public static class MonthBean {
                /**
                 * date : 09月
                 * list : [{"companyName":"宁波心科技有限公司","createDate":"2016.09.14 17:35:45","money":"5000","type":"2"},{"companyName":"湖南省林森科技有限公司","createDate":"2016.09.10 17:35:45","money":"5900","type":"2"}]
                 */
    
                private String date;
                private List<ListBean> list;
    
                public String getDate() {
                    return date;
                }
    
                public void setDate(String date) {
                    this.date = date;
                }
    
                public List<ListBean> getList() {
                    return list;
                }
    
                public void setList(List<ListBean> list) {
                    this.list = list;
                }
    
                public static class ListBean {
                    /**
                     * companyName : 宁波心科技有限公司
                     * createDate : 2016.09.14 17:35:45
                     * money : 5000
                     * type : 2
                     */
    
                    private String companyName;
                    private String createDate;
                    private String money;
                    private String type;
    
                    public String getCompanyName() {
                        return companyName;
                    }
    
                    public void setCompanyName(String companyName) {
                        this.companyName = companyName;
                    }
    
                    public String getCreateDate() {
                        return createDate;
                    }
    
                    public void setCreateDate(String createDate) {
                        this.createDate = createDate;
                    }
    
                    public String getMoney() {
                        return money;
                    }
    
                    public void setMoney(String money) {
                        this.money = money;
                    }
    
                    public String getType() {
                        return type;
                    }
    
                    public void setType(String type) {
                        this.type = type;
                    }
                }
            }
        }
    }
    
    

    因为我是用Retrofit+Rxjava的。所以我们这边就可以直接用

    @GET("accountManage/getOrders.do")
        Observable<Bean> getDealQuery(
                @Query("companyCode")String companyCode,
                @Query("orderID")int orderID,
                @Query("status")int status);
    

    这样我们的JSON就自动转换成了Bean对象,然后我们就对B对象进行相关操作即可。十分方便。比如获取里面的内容,我们就bean.isSuccess()等。

    这里生成的对象类我们用的是Android Studio的插件<GsonFormat>就可以生成。把我们上面的JSON字符串输入,它就能识别,帮忙生成相应的对象类。十分方便。
    链接:插件GsonFormat快速实现JavaBean


    特殊格式

    还是刚那个需求,可能后台不是那么友好,为了自己方便,少几个字段,可能传给你是这样的JSON格式:

    {
        "success": true,
        "msg": "用户查询订单成功",
        "obj": {
            "09月": [
                {
                    "companyName": "宁波心科技有限公司",
                    "createDate": "2016.09.14 17:35:45",
                    "money": "5000",
                    "type": "2"
                },
                {
                    "companyName": "湖南省林森科技有限公司",
                    "createDate": "2016.09.10 17:35:45",
                    "money": "5900",
                    "type": "2"
                }
            ],
            "11月": [
                {
                    "companyName": "杭州心科技有限公司",
                    "createDate": "2016.11.14 17:35:45",
                    "money": "-200",
                    "type": "1"
                },
                {
                    "companyName": "湖南省林森科技有限公司",
                    "createDate": "2016.11.10 17:35:45",
                    "money": "-5900",
                    "type": "1"
                }
            ]
        }
    }
    

    这时候,我们的不同的月份,直接就变成了Key值。然后Key值就会在变化。然后这个月的交易记录内容就变成了这个月份Key值下的value值了。
    说实话,我第一次拿到后台传给这个值的时候,我内心是拒绝的。别怪我太low,我真的没见过key变化的JSON。然后开始想的就是把他继续变成一个对象,来进行处理,我把这个JSON放入到了GsonFormat中,想继续利用插件来生成Bean对象。结果直接报错了。

    为啥,因为GsonFormat插件把JSON变为Bean对象是把这个Key值作为属性名字,毕竟一般都认为Key值不变。但是你的Key值在变化。无法成功生成。

    我的解决方式(提下我用的是GSON):

    把obj部分的内容拿出来。因为obj里面的内容中有key值在变,但还是符合规定的JSON格式。我们可以把他变为JSON对象。

    public class Bean {
    
        private boolean success;
        private String msg;
        private JsonObject obj;
    
        public boolean isSuccess() {
            return success;
        }
    
        public void setSuccess(boolean success) {
            this.success = success;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public JsonObject getObj() {
            return obj;
        }
    
        public void setObj(JsonObject obj) {
            this.obj = obj;
        }
    }
    

    这里的JsonObject是com.google.gson.JsonObject,因为我是用Gson来解析JSON的。

    这样我们就可以顺利的把后台传过来的JSON转成了我们这个新的Bean对象了。我们可以继续用上面的Rtrofit+Rxjava 的代码来访问:

    @GET("accountManage/getOrders.do")
        Observable<Bean> getDealQuery(
                @Query("companyCode")String companyCode,
                @Query("orderID")int orderID,
                @Query("status")int status);
    

    切记不要把这个新的Bean.java中的private JsonObject obj;换成什么private Obeject obj;等,不然等会拿到的Bean对象中的obj部分会是{ }这样,里面是空的。
    为什么?你还好意思问我为什么!? 因为这个obj的JSON部分不能正确转换成对象啊。不然刚那个GsonFormat插件就帮你转成对象了啊!!!!

    好了。我们就拿到这个Bean对象后。我们通过bean.getObj()方法就顺利拿到了JsonObject这个对象了。然后我们在对这个对象进行处理。我们需要对他进行遍历,然后分别拿到里面的Key值及Value值。然后我们可以再对里面的Value值转换成一个对象。

    1. 我们一步步来,先进行遍历,分别拿到Key 和Value:
    JsonObject jsonObject = bean.getObj();
    if (jsonObject != null) {
        Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
        for (Map.Entry<String, JsonElement> entry : entrySet) {
             //entry.getKey()   
             //这是拿到了Key值,也就是我们的month月份值     
             //jsonObject.getAsJsonArray(entry.getKey()) 
             //我们拿到了value里面的值.
             //因为value是一个JSON数组类型,所以我们直接用getAsJsonArray方法来获取。
        }
    }    
    
    1. 我们来把value值转成对象。
      好了。我们就来再建一个类。来把Value值中的JsonArray转成相应的对象。这样后面处理起来也方便。当然这里我们可以继续用我们的GsonFormat插件来生成。
    
    public class ItemBean {
        
        private String companyName;
        private String createDate;
        private String money;
        private String type;
    
        public String getCompanyName() {
            return companyName;
        }
    
        public void setCompanyName(String companyName) {
            this.companyName = companyName;
        }
    
        public String getCreateDate() {
            return createDate;
        }
    
        public void setCreateDate(String createDate) {
            this.createDate = createDate;
        }
    
        public String getMoney() {
            return money;
        }
    
        public void setMoney(String money) {
            this.money = money;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    }
    
    

    转换为把JsonArray转换成List<ItemBean>的代码为:

    Gson googleJson = new Gson();
    List<ItemBean> value =
                   googleJson.fromJson(jsonObject.getAsJsonArray(entry.getKey()), new TypeToken<List<DealQueryInfoBean>>() {
                                                }.getType());
    //转换成泛型类型,后面不能单纯的写成fromJson(XXX,ArrayList.class);
    

    就这样我们成功的把这个特殊的json转换好了。变成了一个新的可操作的对象。后面的逻辑就大家自行写了。😜😜😜😜😜😜

    相关文章

      网友评论

      • 我like砂糖:这种情况下,我直接扔回去给后台:joy:
      • 风舞尘起:请教下 接口返回的key aadd.ssss.fff这种用gson转换直接报错,怎么转
      • 贾亦真亦贾:我觉得大家不要过多的在意API本身的问题,博主解决问题的思路值得我们学习。
      • EJ_CoffeeTime:第一种方式那么处理不太恰当啊,一个请求一个类,还那么多的内部类。。。
      • EJ_CoffeeTime:本来是不想出来评论的,但真的没法忍了。这后台脑子抽了吧,返回一个中文。。。
      • b0be86467f69:不是可以通过Map接收吗
        jblz625:@gengqiquan :+1:
        15bb224abdb0:不服就干,让服务端换格式,提供便于前端解析的格式是服务端的基本素养。做不到或者bb为什么要 在服务端解析的话可以让他走人了,根本不是一个合格的API编写人员
        swensun:我大概也是这么做的,有其他更方便的办法吗?

      本文标题:项目需求讨论-后台返回的特殊JSON处理

      本文链接:https://www.haomeiwen.com/subject/unbjittx.html