使用Gson解析和创建json
- 使用Gson解析和创建json
- 概述
- 创建和json对应的对象
- 使用gson解析json
- 1 解析对象
- 2 解析数组
- 使用gson生成json
- 特殊用法
- 服务器json回调解析实例
概述
本文主要讲述了如果使用gson来解析含有数组和对象等比较复杂的json,比如对象中含有对象,对象中有list等。首先会介绍如何在Android Studio中使用插件方便的将json映射成对象,然后使用gson实现对象和json的相互转化,最后会详细介绍如何使用泛型封装服务器回调。
如果需要手动解析请参考:Android手动创建和解析Json
gson的github地址
A Java serialization/deserialization library to convert Java Objects into JSON and back
一个将Java对象转化成json的Java序列化/反序列化库。
gson主要是用用来解析json为对象和将对象转化成json。
gradle依赖
compile 'com.google.code.gson:gson:2.8.0'
1 创建和json对应的对象
这个可以使用Android Studio的插件,这里推荐使用GsonFormat,直接在Android Studio的设置,插件中搜索GsonFormat,安装之后重启即可使用。新建一个Java类,点击菜单栏的code,Generate…,输入json字符串,在左下角的setting中可以勾选split generate,可以分开生成多个对象。
勾选use serializedName,可以选择自动添加serializedName注解,这是gson的注解,意思是序列化时的名字,json映射的是这个名字,而不是字段名,不加这个注解就是映射字段名。
以下面的json字符串为例:
{
"students": [
{
"name": "jadyli",
"gender": "male",
"age": 18
},
{
"name": "Juliet",
"gender": "female",
"age": 20
}
]
}
生成的对象是
public class StudentInfo {
private List<Student> students;
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "StudentInfo{" +
"students=" + students.toString() +
'}';
}
}
public class Student {
private String name;
private String gender;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
这样一个跟json对应得对象就创建好了。
2 使用gson解析json
2.1 解析对象
解析对象使用fromJson(String json, Class classOfT),后面的class需要传入具体类型。对象里面有对象或数组也可以自动解析哦。
String json = "{\"students\":[{\"name\":\"jadyli\",\"gender\":\"male\",\"age\":18},
{\"name\":\"Juliet\",\"gender\":\"female\",\"age\":20}]}";
StudentInfo studentInfo = new Gson().fromJson(json, StudentInfo.class);
System.out.println(studentInfo.toString());
2.2 解析数组
直接解析数组使用fromJson(String json, Type typeOfT)
这个Type,可以使用TypeToken类获得,比如new TypeToken<List<Student>>() {}.getType()
。
这里的例子我们要提高json的复杂度,下面这个json表示班级信息,有两个班级,A班和B班,每个班级有学生若干。
[
{
"students": [
{
"name": "jadyli",
"gender": "male",
"age": 18
},
{
"name": "Juliet",
"gender": "female",
"age": 20
}
],
"class": "A"
},
{
"students": [
{
"name": "jack",
"gender": "male",
"age": 27
},
{
"name": "Avril",
"gender": "female",
"age": 17
}
],
"class": "B"
}
]
根据json创建相应的对象。我们发现,我们的json中含有Java关键字class,这个时候@SerializedName
注解就派上用场了,我们把字段给为clssX,同时注解里填上真实的名字class
。Student对象不变。
public class ClassInfo {
@SerializedName("class")
private String classX;
private List<Student> students;
public String getClassX() {
return classX;
}
public void setClassX(String classX) {
this.classX = classX;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "ClassInfo{" +
"classX='" + classX + '\'' +
", students=" + students.toString() +
'}';
}
}
解析上面的json数组。
List<ClassInfo> classInfoList = new Gson().fromJson("[" +
"{\"students\":[{\"name\":\"jadyli\",\"gender\":\"male\",\"age\":18}," + "{\"name\":\"Juliet\",\"gender\":\"female\",\"age\":20}],\"class\":\"A\"}," +
"{\"students\":[{\"name\":\"jack\",\"gender\":\"male\",\"age\":27},{\"name\":\"Avril\",\"gender\":\"female\",\"age\":17}],\"class\":\"B\"}]",
new TypeToken<List<ClassInfo>>() {
}.getType());
System.out.println(classInfoList.toString());
3 使用gson生成json
一般toJson(Object src)方法就够用了。
String[] names = {"jadyli", "Juliet"};
String[] genders = {"male", "female"};
int[] ages = {18, 20};
List<Student> students = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
Student student = new Student();
student.setName(names[i]);
student.setGender(genders[i]);
student.setAge(ages[i]);
students.add(student);
}
String jsonStr = new Gson().toJson(students);
System.out.println(jsonStr);
new Gson().toJson(Object src)输出的是没有格式化的json字符串,要是想输出格式化了的,可以使用
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonStr = gson.toJson(students);
默认忽略空的字段,如果不想忽略,可以使用
Gson gson = new GsonBuilder().serializeNulls().create();
String jsonStr = gson.toJson(students);
4 特殊用法
不映射特定成员变量
加上@Expose
注解。然后使用的时候用如下语句创建gson对象。
new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
不映射特定修饰符的成员变量
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE)
.create();
上面的代码会排除static
、transient
、volatile
修饰的成员变量。
指定排除策略
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Foo {
// Field tag only annotation
}
public class SampleObjectForTest {
@Foo private final int annotatedField;
private final String stringField;
private final long longField;
private final Class<?> clazzField;
public SampleObjectForTest() {
annotatedField = 5;
stringField = "someDefaultValue";
longField = 1234;
}
}
public class MyExclusionStrategy implements ExclusionStrategy {
private final Class<?> typeToSkip;
private MyExclusionStrategy(Class<?> typeToSkip) {
this.typeToSkip = typeToSkip;
}
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz == typeToSkip);
}
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(Foo.class) != null;
}
}
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.setExclusionStrategies(new MyExclusionStrategy(String.class))
.serializeNulls()
.create();
SampleObjectForTest src = new SampleObjectForTest();
String json = gson.toJson(src);
System.out.println(json);
}