Android json 数据解析之 Gson 和 FastJson 的应用
一:Gson 应用
Gson 是谷歌提供的一个开源库,能够用来解析 JSON 数据。
1. 什么是 json
json 就是用来进行网络数据传输的一种格局,目前的应用很宽泛,其格局就是一种键值对的模式,很不便进行解析。json 有 Json 对象(JsonObject)和 Json 数组(JsonArray)两种模式。但凡以 {} 就是一个 Json 对象,但凡 [] 就是一个 Json 数组。
{// 一个 Json 对象
"user": "user1",
"pwd": "123456"
}
{// 这个对象有 4 个字段,其中一个是数组
"user": "user1",
"pwd": "123456",
"jsonArray": [// 一个 Json 数组外面有 2 个 Json 对象,每个 Json 对象有 2 个字段
{"user": "user1",
"pwd": "123456"},
{"user": "user2",
"pwd": "123456"}
],
"result": "胜利"
}
2. 增加 Gson 依赖
这是 github 上 19.1kStar 我的项目
在 app 下 build.gradle 增加依赖
implementation ‘com.google.code.gson:gson:2.8.6’
3. 应用 GsonFormat 工具
Gson 是采纳对象映射的形式,所有要为 JSON 数据创立一个 Java 对象来与之对应。
1. 装置 GsonFormat 插件
2. 新建一个类,在类外面按 Alt+ S 键,并将要转换的 Json 数据复制进去
4.Gson 应用
public class User implements Serializable {
/**
* user : user1 * pwd : 123456 * jsonArray : [{"user":"user1","pwd":"123456"},{"user":"user2","pwd":"123456"}] * result : 胜利
*/
private String user;
private String pwd;
private String result;
private List<JsonArrayBean> jsonArray;
public static class JsonArrayBean implements Serializable {
/**
* user : user1 * pwd : 123456 */
private String user;
private String pwd;
public String getUser() {return user;}
public void setUser(String user) {this.user = user;}
public String getPwd() {return pwd;}
public void setPwd(String pwd) {this.pwd = pwd;}
}
public String getUser() {return user;}
public void setUser(String user) {this.user = user;}
public String getPwd() {return pwd;}
public void setPwd(String pwd) {this.pwd = pwd;}
public String getResult() {return result;}
public void setResult(String result) {this.result = result;}
public List<JsonArrayBean> getJsonArray() {return jsonArray;}
public void setJsonArray(List<JsonArrayBean> jsonArray) {this.jsonArray = jsonArray;}
}
解析 JSON 对象
String jsonData="要解析的 Json 字符串";
Gson gson=new Gson();
User user=gson.fromJson(jsonData, User.class);
String result=user.getResult();
Log.d("aa",result);
===========
aa: 胜利
解析 Json 对象外面的数组
// 因为 jsonArray 字段对应的是一个 JSON 数组,所以要用一个 List 来对应
List<User.JsonArrayBean> jsonArrayBeans=user.getJsonArray();
// 取值
for (int i=0;i<jsonArrayBeans.size();i++){User.JsonArrayBean jsonArrayBean=jsonArrayBeans.get(i);
String u=jsonArrayBean.getUser();
Log.d("bb",u);
================
取到的值
bb: user1
bb: user2
解析纯数组
[
{"user": "user8",
"pwd": "123456"},
{"user": "user9",
"pwd": "123456"}
]
// 应用形式
Gson gson=new Gson();
List<Data> datas=gson.fromJson(jsonData, new TypeToken<ArrayList<Data>>(){}.getType());
for (int i=0;i<datas.size();i++){Data data=datas.get(i);
String u=data.getUser();
Log.d("cc",u);
}
// 打印后果
cc: user8
cc: user9
序列化对象成 Json(Teacher 对象下 4 个属性 age,email,isDeveloper,name)
Gson gson=new Gson();
Teacher teacher=new Teacher("Rocky","111@qq.com",22,true);
String teacherJson=gson.toJson(teacher);
Log.d("bb",teacherJson);
打印后果
bb {"age":22,"email":"111@qq.com","isDeveloper":true,"name":"Rocky"}
如果变量为空值的话序列化和反序列化
1. 可见某个变量为 null 时,Gson 在序列化的时候间接把这个变量疏忽了
2. 对于 JSON 字符串里没有的变量,Gson 在反序列化时会给它一个默认值,int 类型默认为 0,bool 类型默认为 false,String 类型默认为 null
Gson gson=new Gson();
Teacher teacher=new Teacher("Rocky",null,22,true);
String teacherJson=gson.toJson(teacher);
Log.d("bb",teacherJson);
管制序列化 / 反序列化的变量名称
以 Teacher 对象为例,如果 JSON 字符串的变量名 name 变成 fullName, 无需缓和,咱们也不必把 Teacher 对象的变量 name 改成 fullName, 而后把 get,set 办法全改了。只须要用 Gson 提供的注解 @SerializedName 就行。
public class Teacher{@SerializedName("fullName")
//@SerializedName(value = "name", alternate = "fullName")
// 然而事实远比设想中简单,这个 JSON 有时候传的是 `fullName`,有时候传的是 `name`,这时该怎么办呢?不必放心,`@SerializedName` 承受两个参数,`value` 和 `alternate`,顾名思义,`alternate` 是备选变量名
private String name;
private String email;
private int age;
private boolean isDeveloper;
}
打印 Json 后果
{"age":22,"isDeveloper":true,"fullName":"Rocky"}
序列化 / 反序列化过程中疏忽某些变量
public class Teacher {@SerializedName("fullName")
private String name;
private String email;
//@Expose()参加序列化和反序列化
//@Expose(serialize = false)不参加序列化,只参加反序列化
// @Expose(deserialize = false)只参加序列化,不参加反序列化
@Expose(serialize = false,deserialize = false)// 序列化和反序列化都不参加
private int age;
private boolean isDeveloper;
}
然而:要应用这个注解来管制序列化和反序列化,就不能应用默认的 Gson 对象
//Gson gson=new Gson(); 不能通过这种形式构建 Gson 对象
GsonBuilder builder=new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
//builder.setPrettyPrinting();
Gson gson=builder.create();
Teacher teacher=new Teacher("Rocky","11@qq.com",22,true);
String teacherJson=gson.toJson(teacher);
Log.d("bb",teacherJson);
打印后果
bb: {} 我不晓得为什么这种形式呈现的后果是空,按理说我只是限定一个属性的序列化形式依照网上说的形式构建的 Gson 也不能
我把 builder.excludeFieldsWithoutExposeAnnotation(); 换成 builder.setPrettyPrinting(); 能够打印进去
然而没有限度字段的序列化和反序列化
形式二:transient 字段
通过 private transient int age;
Gson gson=new Gson();
Teacher teacher=new Teacher("Rocky","11@qq.com",22,true);
String teacherJson=gson.toJson(teacher);
Log.d("bb",teacherJson);
打印后果
{"email":"11@qq.com","isDeveloper":true,"fullName":"Rocky"}
二:FastJson 应用
FastJson 是一个 Java 语言的编写的高性能的 Json 处理器,由阿里巴巴公司开发的,github 上 23kStar
1. 增加依赖
implementation ‘com.alibaba:fastjson:1.2.73’
2. 序列化 Json,把对象转成 Json 串调用 JSON.toJSONString
tudent student=new Student("Mike",12);
String studentJson =JSON.toJSONString(student,true);// 为 true 就是要格式化 Json,flase 就是非格式化 Json
//Gson 的 builder.setPrettyPrinting(); 格式化 Json
Log.d("aa",studentJson);
打印后果:aa: {
"age":12,
"name":"Mike"
}
3. 反序列化 Json, 把 Json 串转成对象 JSON.parseObject
String json = "{"age":18,"name":"Rocky"}";
Student student=JSON.parseObject(json,Student.class);// 要记得 Student 增加一个无参的构造方法
Log.d("bb",student.getName());
Log.d("bb",student.getAge()+"");
打印后果
bb: Rocky
bb: 18
如果没有无参的构造方法会报谬误
Json 转成简单的 Bean, 如 List ,Set,Map
public class Student {
private String name;
private int age;
.... 疏忽 get,set 办法
}
一:List 形式
String json = "[{"age":18,"name":"Rocky"},{"age":19,"name":"jack"}]";
List<Student> lists=JSON.parseObject(json,new TypeReference<ArrayList<Student>>(){});
for (int i=0;i<lists.size();i++){Student student=lists.get(i);
Log.d("cc",student.getName());
Log.d("cc",student.getAge()+"");
}
二:Set 形式
String json = "[{"age":18,"name":"Rocky"},{"age":19,"name":"jack"}]";
Set<Student> lists=JSON.parseObject(json,new TypeReference<HashSet<Student>>(){});
for (Student student:lists){Log.d("cc",student.getName());
Log.d("cc",student.getAge()+"");
}
打印后果
cc: Rocky
cc: 18
cc: jack
cc: 19
@JSONField 注解的应用
1. 作用于 get 办法上:当把注解作用于 get 办法上的时候,在把 Java 对象转化成 Json 字符串的时候,Java 对象中的字段名会转化为注解中的 name 指定的字段名。
@JSONField(name = "myAge")
public int getAge() {return age;}
Student student=new Student();
student.setAge(15);
student.setName("Rock");
String studentJson =JSON.toJSONString(student,true);
Log.d("aa",studentJson);
打印后果
aa: {
"myAge":15,// 变成咱们正文的属性名
"name":"Rock"
}
2 作用于 set 办法上:在把 json 字符串转化成 java 对象的时候,注解中的 name 指定的字段名会映射为 Java 对象中的字段名。
@JSONField(name = "myName")
public void setName(String name) {this.name = name;}
String json = "{"age":2,"myName":"ss"}";// 这个 Json 串的属性换成标记的
Student student= JSON.parseObject(json,Student.class);
Log.d("cc",student.getName());
Log.d("cc",student.getAge()+"");
打印后果
cc: ss
cc: 2
3 @JSONField 作用于 java 类的字段上
public class Student {@JSONField(name = "name", alternateNames = {"myName", "meName"})
private String name;
private int age;
}
String json = "{"age":2,"meName":"ss"}";// 这个 name 字段能够是 myName,也能够是 meName 都能够映射到 name 字段上
Student student= JSON.parseObject(json,Student.class);
Log.d("cc",student.getName());
Log.d("cc",student.getAge()+"");
打印后果
cc: ss
cc: 2
Java Bean 对象与 JSONObject 对象互相转换
Java Bean 对象 —>JSONObject 对象 —>json 字符串
student.setAge(15);
student.setName("Rock");
JSONObject jsonObject= (JSONObject) JSON.toJSON(student);//JSONObject 对象
String studentJson= jsonObject.toJSONString();// 转成 Json 字符串,toString()也能够
Log.d("aa",studentJson);
json 字符串与 JSONObject 对象转换
json 字符串 —>JSONObject 对象
String json = "{"age":2,"meName":"ss"}";
JSONObject studentObject= JSON.parseObject(json);
json 字符串转成 Java 汇合能够间接应用 JSON.parseArray()
String json = "[{"age":18,"name":"Rocky"},{"age":19,"name":"jack"}]";
List<Student> lists=JSON.parseArray(json,Student.class);
for (Student student:lists){Log.d("cc",student.getName());
Log.d("cc",student.getAge()+"");
}
END: 所求皆吾愿,所行化坦途