写在前面:
测试的时候我申请了一个查询快递的接口,其返回的JSON数据示例如下:
{
"resultcode": "200", /* 老版状态码,新用户请忽略此字段 */
"reason": "查询物流信息成功",
"result": {
"company": "EMS", /* 快递公司名字 */
"com": "ems",
"no": "1186465887499", /* 快递单号 */
"status": "1", /* 1表示此快递单的物流信息不会发生变化,此时您可缓存下来;0表示有变化的可能性 */
"list": [
{
"datetime": "2016-06-15 21:44:04", /* 物流事件发生的时间 */
"remark": "离开郴州市 发往长沙市【郴州市】", /* 物流事件的描述 */
"zone": "" /* 快件当时所在区域,由于快递公司升级,现大多数快递不提供此信息 */
},
{
"datetime": "2016-06-15 21:46:45",
"remark": "郴州市邮政速递物流公司国际快件监管中心已收件(揽投员姓名:侯云,联系电话:)【郴州市】",
"zone": ""
},
]
},
"error_code": 0 /* 错误码,0表示查询正常,其他表示查询不到物流信息或发生了其他错误 */
}
在解析JSON数据时,如果是用{}括起来的则可视为一个对象,如果是用[]括起来的则可是为一个数组。
一、使用JSONObject解析
分析返回的JSON数据,我们想获取的部分是"list"里面的数组。而最外层开始是一个JSONObject对象。解析思路为:由外到内逐层读取,根据JSON的数据类型去创建JSONObject或者JSONArray,如果是JSONObject,就根据属性名称读取属性值,如果是JSONArray,就遍历数组逐个获取JSONObject:
/**
* 使用JSONObject解析JSON数据
* */
private String parseJSONWithJSONObject(String jsonData){
StringBuilder result = new StringBuilder();
try {
JSONObject dataObject = new JSONObject(jsonData);
if("200".equals(dataObject.getString("resultcode"))){
JSONObject resultObject = dataObject.getJSONObject("result");
JSONArray resultArray = resultObject.getJSONArray("list");
for(int i=0;i<resultArray.length();i++){
JSONObject itemObject = resultArray.getJSONObject(i);
String dateTime = itemObject.getString("datetime");
String remark = itemObject.getString("remark");
result.append("时间:"+dateTime+"\r\n"+"内容:"+remark+"\r\n");
}
return result.toString();
}else {
return null;
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
二、使用GSON解析
1.在app/build.gradle中添加GSON库的依赖
implementation 'com.google.code.gson:gson:2.8.5'
2.根据JSON的数据结构去创建Java Bean类
最外层:
public class Data {
private String resultcode;
private String reason;
private int error_code;
private Logistics result;
......
}
次外层:
public class Logistics {
private String company;
private String com;
private String no;
private String status;
private List<Status> list;
......
}
内层:
public class Status {
private String datetime;
private String remark;
private String zone;
......
}
3.先获取Gson的实例,然后调用其fromJson()方法解析JSON数据得到数据对象,这样我们就可以通过get方法逐层读取想要的数据了。
/**
* 使用GSON解析JSON数据
* */
private String parseJSONWithGSON(String jsonData){
StringBuilder result = new StringBuilder();
Gson gson = new Gson();
Data data = gson.fromJson(jsonData,Data.class);
Logistics logistics = data.getResult();
List<Status> statusList = logistics.getList();
for(Status status:statusList){
String dateTime = status.getDatetime();
String remark = status.getRemark();
result.append("时间:"+dateTime+"\r\n"+"内容:"+remark+"\r\n");
}
return result.toString();
}
三、关于GSON的补充
假设有这么一段JSON数据如下:
String json = {"a":"100","b":[{"b1":"b_value1","b2":"b_value2"}, {"b1":"b_value1","b2":"b_value2"}],"c": {"c1":"c_value1","c2":"c_value2"}}
1.Java Bean类里面的成员变量名称必须和JSON数据中的key值保持一致(但是类名可以自定义)或者采用@SerializedName注解的方式来让JSON字段和JAVA字段之间建立映射关系,如下:
public class JavaBean {
@SerializedName("a")
public String resultCode;
public List<B> b;
public C c;
......
}
2.如果最外层就是JSONArray,那么在调用gson.fromJson()方法时,传参要相应变化:
Gson gson = new Gson();
List<Person> people = gson.fromJson(jsonData, new TypeToken<List<Person>>(){}.getType());