基础知识:
-
- 建议使用 private 修饰属性。
- 不需要使用任何注解来表明一个属性是否应该序列化和反序列化。默认情况下,当前类的所有属性(以及从父类继承的属性)都将被参与序列化和反序列化。
- 如果一个属性被
transient
修饰,默认情况下该属性会被忽略掉,并且不参与 JSON 的序列化和反序列化。 - 在序列化的时候,一个值为 null 的字段不会在输出中出现。
- 在反序列化时,JSON 中缺少的条目导致将对象中的相应字段设置为null。
可以通过调用 new Gson()
来创建一个 Gson 对象。 GsonBuilder
类来创建同时也可以创建Gson对象,这种创建方式允许自定义多种配置信息。
一、Gson生成Json数据
在使用Gson之前我们应该导入GSON包
首先创建一个JavaBean:
public class Student { private String name; private String sex; private int age; private String[] courses; public Student() { //无参构造方法 } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String[] getCourses() { return courses; } public void setCourses(String[] courses) { this.courses = courses; } }在布局文件中仅仅添加了一个按钮
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="android.coolweather.com.gsondemo2.MainActivity"> <Button android:id="@+id/btn_tojson" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="toJsonByGson" android:text="生成Json数据"/> </LinearLayout>Activity代码
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void toJsonByGson(View view){ Student zhang=getStudent(); Gson gson=new Gson(); //序列化 String jsonStr=gson.toJson(zhang); Log.d("MVE","jsonStr:"+jsonStr); //MVE: jsonStr:{"age":21,"courses":["C语言","Java","TCP/IP"],"name":"zhang","sex":"男"} } public Student getStudent() { Student student=new Student(); student.setName("zhang"); student.setSex("男"); student.setAge(21); student.setCourses(new String[]{"C语言","Java","TCP/IP"}); return student; } }
这样很简单的就将一个对象序列化为Json数据。
如果我们将javabean添加一个属性,并且该属性使用transient修饰(默认情况下该属性会被忽略掉,并且不参与 JSON 的序列化和反序列化)
public class Student { .... private transient String item; ..... public String getItem() { return item; } public void setItem(String item) { this.item = item; } }为item字段设值
public Student getStudent() { .... student.setItem("我会被忽略!"); return student; } }结果:
{"age":21,"courses":["C语言","Java","TCP/IP"],"name":"zhang","sex":"男"}可以看到该属性在序列化的时候被忽略了。
可以注意到默认情况下生成的Json对象的名/值对中的名和我们属性名称是一样的,如果我们想让它在转为Json对象时按照我们自己规定的名显示可以采用注解的方式
public class Student{ @SerializedName("NAME") private String name; @SerializedName("SEX") private String sex; .... }结果:
{"age":21,"courses":["C语言","Java","TCP/IP"],"NAME":"zhang","SEX":"男"}
Gson 默认的 JSON 字符串输出格式是紧凑类型的 JSON 字符串格式。也就是说,输出的 JSON 字符串结构中没有任何的空格,同样的,在键/值之间、数组中的每个对象之间也都没有空格。同时,值为 null 的字段也会被忽略掉。如果你希望使用 Pretty Print 功能,必须使用 GsonBuilder
来配置你的 Gson 对象。
public void toJsonByGson(View view){ Student zhang=getStudent(); GsonBuilder gsBuilder=new GsonBuilder(); //setPrettyPrinting()没有实际的作用,可以美化Json的格式 gsBuilder.setPrettyPrinting(); Gson gson= gsBuilder.create(); //序列化 String jsonStr=gson.toJson(zhang); Log.d("MVE","jsonStr:"+jsonStr); }结果:可以看到Json的格式更加人性化了
{ "age": 21, "courses": [ "C语言", "Java", "TCP/IP" ], "NAME": "zhang", "SEX": "男" }使用
GsonBuilder
可以配置更多的策略,我们可以不在javabean中使用注解的方式也可以达到同样的效果。
public class Student{ private String name; private String sex; private int age; private String[] courses; private transient String item; ....}
public void toJsonByGson(View view){ Student zhang=getStudent(); GsonBuilder gsBuilder=new GsonBuilder(); //setPrettyPrinting()没有实际的作用,可以美化Json的格式 gsBuilder.setPrettyPrinting(); gsBuilder.setFieldNamingStrategy(new FieldNamingStrategy() { @Override public String translateName(Field f) { if (f.getName().equals("name")){ return "M_NAME"; } return f.getName(); } }); Gson gson= gsBuilder.create(); //序列化 String jsonStr=gson.toJson(zhang); Log.d("MVE","jsonStr:"+jsonStr); }
结果:
{ "age": 21, "courses": [ "C语言", "Java", "TCP/IP" ], "M_NAME": "zhang", "sex": "男" }
二、Gson解析Json数据
在布局文件中再添加一个按钮
<Button android:id="@+id/btn_fromjson" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="fromJsonByGson" android:text="解析Json数据" />
准备一个Json数据
{"age":23,"courses":["C语言","JavaEE","TCP/IP","Android"],"M_NAME":"li","sex":"女"}Activity
public void fromJsonByGson(View view){ String json="{\"age\":21,\"courses\":[\"C语言\",\"Java\",\"TCP/IP\"],\"name\":\"zhang\",\"sex\":\"男\"}"; Gson gson=new Gson(); Student li=gson.fromJson(json,Student.class); Log.d("MVE","li="+li); }结果:
li=Student{name='li', sex='女', age=23, courses=[C语言, JavaEE, TCP/IP, Android], item='null'}三、带日期的Json数据
在javabean中添加一个属性
public class Student{ ... private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } ... @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + ", age=" + age + ", courses=" + Arrays.toString(courses) + ", item='" + item + '\'' + ", birthday=" + birthday + '}'; } }一个带日期的Json数据如下:
{"age":17,"birthday":"11-05-05","courses":["C语言","Java","TCP/IP"],"name":"li","sex":"女"}Activity:
public void fromJsonByGson(View view){ String json="{\"age\":17,\"birthday\":\"11-05-05\",\"courses\":[\"C语言\",\"Java\",\"TCP/IP\"],\"name\":\"li\",\"sex\":\"女\"}"; GsonBuilder gsBuilder=new GsonBuilder(); gsBuilder.setDateFormat("yy-MM-dd"); Gson gson=gsBuilder.create(); Student li=gson.fromJson(json,Student.class); Log.d("MVE","li="+li); }结果:
li=Student{name='li', sex='女', age=17, courses=[C语言, Java, TCP/IP], item='null', birthday=Thu May 05 00:00:00 GMT+00:00 2011}