美文网首页
Android Json不规则键值解析与转换

Android Json不规则键值解析与转换

作者: 隐姓埋名的猫大叔 | 来源:发表于2020-12-24 16:18 被阅读0次

    简述

    在Android开发的时候,通过网络请求获取后台返回数据与上传数据给后台是十分常见的。有时候,我们会遇到需要解析和传递特殊键值的Json,对于这种情况,引出了本次要讲诉的内容。

    Json数据解析

    开发的时候可能会遇到如下要解析奇葩json字段

    //[]中代表报名该选修课的学生id
    {"ret":0,
        "response":{
            "tag_category":{
                "选修课":{
                    "红楼梦名著解析":["1","2","7","8"],
                    "书法之美":["1","2","3","4","5"]
                }
                
            }
        }
    }
    

    有的小伙伴可能会想到,我们可以通过使用谷歌的Gson解析

    implementation 'com.google.code.gson:gson:2.8.0'
    

    将我们上文要解析的封装成javaBean,结果如下

    public class ClassCourses {
    
        /**
         * ret : 0
         * response : {"tag_category":{"选修课":{"红楼梦名著解析":["1","2","7","8"],"书法之美":["1","2","3","4","5"]}}}
         */
    
        private int ret;
        private ResponseBean response;
    
        public int getRet() {
            return ret;
        }
    
        public void setRet(int ret) {
            this.ret = ret;
        }
    
        public ResponseBean getResponse() {
            return response;
        }
    
        public void setResponse(ResponseBean response) {
            this.response = response;
        }
    
        public static class ResponseBean {
            /**
             * tag_category : {"选修课":{"红楼梦名著解析":["1","2","7","8"],"书法之美":["1","2","3","4","5"]}}
             */
    
            private TagCategoryBean tag_category;
    
            public TagCategoryBean getTag_category() {
                return tag_category;
            }
    
            public void setTag_category(TagCategoryBean tag_category) {
                this.tag_category = tag_category;
            }
    
            public static class TagCategoryBean {
                /**
                 * 选修课 : {"红楼梦名著解析":["1","2","7","8"],"书法之美":["1","2","3","4","5"]}
                 */
    
                private 选修课Bean 选修课;
    
                public 选修课Bean get选修课() {
                    return 选修课;
                }
    
                public void set选修课(选修课Bean 选修课) {
                    this.选修课 = 选修课;
                }
    
                public static class 选修课Bean {
                    private List<String> 红楼梦名著解析;
                    private List<String> 书法之美;
    
                    public List<String> get红楼梦名著解析() {
                        return 红楼梦名著解析;
                    }
    
                    public void set红楼梦名著解析(List<String> 红楼梦名著解析) {
                        this.红楼梦名著解析 = 红楼梦名著解析;
                    }
    
                    public List<String> get书法之美() {
                        return 书法之美;
                    }
    
                    public void set书法之美(List<String> 书法之美) {
                        this.书法之美 = 书法之美;
                    }
                }
            }
        }
    }
    

    然后请求的时候再对应解析

    public class MainActivity extends AppCompatActivity {
    
        private Gson gson=new GsonBuilder().create();
        private String json1="{\"ret\":0,\n" +
                "    \"response\":{\n" +
                "        \"tag_category\":{\n" +
                "            \"选修课\":{\n" +
                "                \"红楼梦名著解析\":[\"1\",\"2\",\"7\",\"8\"],\n" +
                "                \"书法之美\":[\"1\",\"2\",\"3\",\"4\",\"5\"]\n" +
                "            }\n" +
                "            \n" +
                "        }\n" +
                "    }\n" +
                "}";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ClassCourses classCourses=gson.fromJson(json1,ClassCourses.class);
            classCourses.getResponse().getTag_category().get选修课().get书法之美();
        }
    }
    

    这种做法虽然可以解析当前的,但是当后台增加了新的报名课程,如新增:西游记解读,此时,再用这个封装的类去解析,会发现解析不了。我们不可能知道什么时候会出现新的课程,这种动态新增此时是不适应上诉方法。

    为此,我们可以通过JSONObject 依次取出,还是上面的数据,我们观察了下它的结构,发现我们只需要获取选修课这个列表,每个课程对应有一个选修的学生集合,我们自己设计一个SelectCoursesBean

    public class SelectCoursesBean {
        private String className;
        private List<String> studentId;
    
    
        public String getClassName() {
            return className;
        }
    
        public void setClassName(String className) {
            this.className = className;
        }
    
        public List<String> getStudentId() {
            return studentId;
        }
    
        public void setStudentId(List<String> studentId) {
            this.studentId = studentId;
        }
    
        @Override
        public String toString() {
            return "SelectCoursesBean{" +
                    "className='" + className + '\'' +
                    ", studentId=" + studentId +
                    '}';
        }
    }
    
    

    然后在我们要解析的界面一层层取出键和值
    analysisByJSONObject() 函数如下:

        private void analysisByJSONObject() {
            List<SelectCoursesBean> coursesBeanList=new ArrayList<>();
            try {
                JSONObject object=new JSONObject(json);
                JSONObject response=new JSONObject(object.get("response").toString());
                JSONObject tag_category=new JSONObject(response.get("tag_category").toString());
                JSONObject course=new JSONObject(tag_category.get("选修课").toString());
                Iterator<String> keys=course.keys();
                while (keys.hasNext()){
                    String key=keys.next();//课程名
    
                    List<String> studentId=new ArrayList<>();
                    //通过JSONArray  一个个值遍历打出来
                    JSONArray jsonArray=new JSONArray(course.get(key).toString());
                    for(int i=0;i<jsonArray.length();i++){
                        studentId.add(jsonArray.get(i).toString());
                    }
                    SelectCoursesBean coursesBean=new SelectCoursesBean();
                    coursesBean.setClassName(key);
                    coursesBean.setStudentId(studentId);
                    coursesBeanList.add(coursesBean);
                }
    
            } catch (JSONException e) {
                e.printStackTrace();
            }
    
            Log.e("TAG","数据结果:"+coursesBeanList.toString());
        }
    

    如果觉得for循环麻烦,还是可以用Gson+JSONObject 混合着用,没有区别,思路是一样的

        private void anotherAnalysis() {
            Gson gson=new GsonBuilder().create();
            List<SelectCoursesBean> coursesBeanList=new ArrayList<>();
            try {
                JSONObject object=new JSONObject(json);
                JSONObject response=new JSONObject(object.get("response").toString());
                JSONObject tag_category=new JSONObject(response.get("tag_category").toString());
                JSONObject course=new JSONObject(tag_category.get("选修课").toString());
                Iterator<String> keys=course.keys();
                while (keys.hasNext()){
                    String key=keys.next();//课程名
                    String value=course.optString(key);//学生ID json
                    //为了方便还可以用谷歌的,
                    List<String> studentId=gson.fromJson(value,List.class);
                    SelectCoursesBean coursesBean=new SelectCoursesBean();
                    coursesBean.setClassName(key);
                    coursesBean.setStudentId(studentId);
                    coursesBeanList.add(coursesBean);
                }
    
    
            } catch (JSONException e) {
                e.printStackTrace();
            }
              Log.e("TAG","数据结果:"+coursesBeanList.toString());
        }
    

    其中打印出来的结果如下:

    数据结果:[SelectCoursesBean{className='红楼梦名著解析', studentId=[1, 2, 7, 8]}, SelectCoursesBean{className='书法之美', studentId=[1, 2, 3, 4, 5]}]
    
    转换成Json 数据

    有时候也会遇到后台要求上传回去带有特殊键值的Json,如下:

    {"courses": {
      "语文": {    
       "teacher":"李老师" ,
       "minutes": 90   
      },
      "数学": {
       "teacher":"赵老师" ,
       "minutes": 120
      },
      "英语": {
       "teacher":"孙老师" ,
       "minutes": 60
      }
     }}
    

    需要上传课程,每个老师的相关信息与授课时间,观察了下它的结构,发现一个集合里一个课程名称配对一个老师相关信息,这个和map很相似(键需唯一),因此我们写个自定义对象,设置完数据后,再转换成json。
    CourseModel 模型如下

    public class CourseModel {
        private Map<String,Course> courses;
    
    
        public Map<String, Course> getCourses() {
            return courses;
        }
    
        public void setCourses(Map<String, Course> courses) {
            this.courses = courses;
        }
    
        public static class Course{
            private String teacher;//教师名称
            private String minutes;//分钟
    
            public Course(String teacher, String minutes) {
                this.teacher = teacher;
                this.minutes = minutes;
            }
    
            public String getTeacher() {
                return teacher;
            }
    
            public void setTeacher(String teacher) {
                this.teacher = teacher;
            }
    
            public String getMinutes() {
                return minutes;
            }
    
            public void setMinutes(String minutes) {
                this.minutes = minutes;
            }
    
            @Override
            public String toString() {
                return "Course{" +
                        "teacher='" + teacher + '\'' +
                        ", minutes='" + minutes + '\'' +
                        '}';
            }
        }
    
        @Override
        public String toString() {
            return "CourseModel{" +
                    "courses=" + courses +
                    '}';
        }
    }
    
    

    通过Gson 将对象解析成Json 数据

        private void useGsonToParseJson() {
            Gson gson=new Gson();
            CourseModel.Course course1=new CourseModel.Course("李老师","90");
            CourseModel.Course course2=new CourseModel.Course("赵老师","120");
            CourseModel.Course course3=new CourseModel.Course("孙老师","60");
            CourseModel courseModel=new CourseModel();
            Map<String, CourseModel.Course> map=new HashMap<>();
            map.put("语文",course1);
            map.put("数学",course2);
            map.put("英语",course3);
            courseModel.setCourses(map);
            Log.e("gson","上传参数:"+ gson.toJson(courseModel));
    
        }
    

    打印结果如下:

    E/gson: 上传参数:{"courses":{"数学":{"minutes":"120","teacher":"赵老师"},"语文":{"minutes":"90","teacher":"李老师"},"英语":{"minutes":"60","teacher":"孙老师"}}}
    

    至此,json解析与转换的简单使用就到此为止了。开发中遇到这种情况,可以的话先与后台沟通,这边遇到的这种情况是由于其后台祖传代码,要修改已经很难。。。不得已为之。

    相关文章

      网友评论

          本文标题:Android Json不规则键值解析与转换

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