使用Gson解析和创建json
-
-
概述
本文主要讲述了如果使用gson来解析含有数组和对象等比较复杂的json,比如对象中含有对象,对象中有list等。首先会介绍如何在Android Studio中使用插件方便的将json映射成对象,然后使用gson实现对象和json的相互转化,最后会详细介绍如何使用泛型封装服务器回调。
如果需要手动解析请参考:Android手动创建和解析Json
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
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 } ] }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
生成的对象是
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() + '}'; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
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 + '}'; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
这样一个跟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());
- 1
- 2
- 3
- 4
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" } ]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
根据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() + '}'; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
解析上面的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());
- 1
- 2
- 3
- 4
- 5
- 6
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);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
new Gson().toJson(Object src)输出的是没有格式化的json字符串,要是想输出格式化了的,可以使用
Gson gson = new GsonBuilder().setPrettyPrinting().create(); String jsonStr = gson.toJson(students);
- 1
- 2
默认忽略空的字段,如果不想忽略,可以使用
Gson gson = new GsonBuilder().serializeNulls().create(); String jsonStr = gson.toJson(students);
- 1
- 2
4 特殊用法
不映射特定成员变量
加上@Expose
注解。然后使用的时候用如下语句创建gson对象。new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
- 1
不映射特定修饰符的成员变量
Gson gson = new GsonBuilder() .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT, Modifier.VOLATILE) .create();
- 1
- 2
- 3
上面的代码会排除
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); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
4 服务器json回调解析实例
这个比较复杂,放到了下一篇博客
-