android键值列表,Android Json不规则键值解析与转换

简述

在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 红楼梦名著解析;

private List 书法之美;

public List get红楼梦名著解析() {

return 红楼梦名著解析;

}

public void set红楼梦名著解析(List 红楼梦名著解析) {

this.红楼梦名著解析 = 红楼梦名著解析;

}

public List get书法之美() {

return 书法之美;

}

public void set书法之美(List 书法之美) {

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 studentId;

public String getClassName() {

return className;

}

public void setClassName(String className) {

this.className = className;

}

public List getStudentId() {

return studentId;

}

public void setStudentId(List studentId) {

this.studentId = studentId;

}

@Override

public String toString() {

return "SelectCoursesBean{" +

"className='" + className + '\'' +

", studentId=" + studentId +

'}';

}

}

然后在我们要解析的界面一层层取出键和值

analysisByJSONObject() 函数如下:

private void analysisByJSONObject() {

List 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 keys=course.keys();

while (keys.hasNext()){

String key=keys.next();//课程名

List studentId=new ArrayList<>();

//通过JSONArray 一个个值遍历打出来

JSONArray jsonArray=new JSONArray(course.get(key).toString());

for(int i=0;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 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 keys=course.keys();

while (keys.hasNext()){

String key=keys.next();//课程名

String value=course.optString(key);//学生ID json

//为了方便还可以用谷歌的,

List 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 courses;

public Map getCourses() {

return courses;

}

public void setCourses(Map 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 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解析与转换的简单使用就到此为止了。开发中遇到这种情况,可以的话先与后台沟通,这边遇到的这种情况是由于其后台祖传代码,要修改已经很难。。。不得已为之。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值