项目地址:
Oschina:https://git.oschina.net/ysx_xx/GsonText
详解Gson使用(一)简单对象转化
http://blog.csdn.net/a249900679/article/details/51385913
详解Gson使用(二)带泛型的List转化
http://blog.csdn.net/a249900679/article/details/51386028
详解Gson使用(三)使用注解
http://blog.csdn.net/a249900679/article/details/51386509
http://blog.csdn.net/a249900679/article/details/51386660
详解Gson使用(五)实现百度翻译功能
http://blog.csdn.net/a249900679/article/details/51386727
前几篇介绍的方法都是直接使用new Gson(),toJson()和fromJson()方法,这会将全部的字段序列化或反序列化,但实际中,有时我们并不需要全部字段序列化。或者随着项目的发展,版本可能会升级,某些实体类里可能会新增几个字段,这时版本不同数据不同,即低版本不能解析新的json数据(因为新的数据还有新增的字段)等。
遇到上面的问题怎么办?Gson提供了GsonBuilder,我们可以用GsonBuilder来生成Gson对象,规定Gson的序列化或反序列化的格式。
GsonBuilder().registerTypeAdapter(Id.class, new IdTypeAdapter())//自定义类型适配器
GsonBuilder().enableComplexMapKeySerialization()//Map类型
GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)//会把字段首字母大写
GsonBuilder().setVersion(1.0)//自定义版本号
GsonBuilder还有很多中方法,下面来介绍它的使用注解定制序列化字段等方法:
1. 使用注解自定义哪些字段需要序列化或反序列化,没有@Expose注解的不会被序列化,serialize为false代表不序列化, deserialize则代表反序列化:
实体类:
public class GsonBuilderBeanOne {
@Expose
private String username;
@Expose(serialize = false, deserialize = true)
private String password;
@Expose(serialize = true, deserialize = false)
private String school;
private String classroom;
@Expose(serialize = false)
private String sex;
public GsonBuilderBeanOne(String username, String password, String school,
String classroom, String sex) {
super();
this.username = username;
this.password = password;
this.school = school;
this.classroom = classroom;
this.sex = sex;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getSchool() {
return school;
}
public String getClassroom() {
return classroom;
}
public String getSex() {
return sex;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setSchool(String school) {
this.school = school;
}
public void setClassroom(String classroom) {
this.classroom = classroom;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
String resultString = "";
resultString += "username:" + username + "\npassword:" + password
+ "\nschool:" + school + "\nclassroom:" + classroom + "\nsex:"
+ sex + "\n";
return resultString;
}
}
将对象序列化,默认情况下@Expose注解是不起作用的,需要用GsonBuilder创建Gson的时候调用了GsonBuilder.excludeFieldsWithoutExposeAnnotation()方法:
private String ten() {
Gson gson2 = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
.create();
GsonBuilderBeanOne gsonBuilderBeanOne = new GsonBuilderBeanOne("144",
"123", "华软", "软工五班", "男");
return gson2.toJson(gsonBuilderBeanOne);
}
结果为:
可以看到序列化结果只有school和username,是因为password跟sex使用了注解同时规定序列化为false,而classroom之所以没有序列化,是因为它没有使用注解
再来看看将json数据转换为该对象:
private String ten() {
Gson gson2 = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String showString = "";
String jsonString = "{'username':'144','password':'123','school':'华软','classroom':'软工五班','sex':'男'}";
showString += "json:" + jsonString + "\n解析后的数据:\n";
GsonBuilderBeanOne beanOne = gson2.fromJson(jsonString, GsonBuilderBeanOne.class);
showString += beanOne.toString();
showString += "----------------------\n";
return showString;
}
结果为:
可以看到school跟classroom为null,是因为school使用注解并规定反序列化为false,而classroom没有使用注解
2. 使用注解自定义序列化字段名称,直接用Gson就可以,不用GsonBuilder生成对象
实体类:public class GsonBuilderBeanTwo {
@SerializedName("name")
private String username;
@SerializedName("pwd")
private String password;
public GsonBuilderBeanTwo(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
String resultString = "";
resultString += "username:" + username + "\npassword:" + password
+ "\n";
return resultString;
}
}
规定username序列化对应字段名称为name,password对应字段名称为pwd
将对象序列化:private String eleven() {
GsonBuilderBeanTwo gsonBuilderBeanTwo = new GsonBuilderBeanTwo("144", "123");
return gson.toJson(gsonBuilderBeanTwo);
}
结果为:
可以看到json中的键变成name和pwd,而像之前的那些是username、password
3. 最后介绍,使用注解表示哪些字段是哪个版本的,@Since(1.0)代表1.0版本,应用版本比它高或同等时会被序列化,反之不会,也可以用@Until(1.0)
实体类:
public class GsonBuilderBeanThree {
@Since(1.0)
private String username;
@Since(1.1)
private String password;
public GsonBuilderBeanThree(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
String resultString = "";
resultString += "username:" + username + "\npassword:" + password + "\n";
return resultString;
}
}
上面实体类中,username表示1.0版本就有的,而password则表示1.1版本才加进来的字段
将对象实例化,需要设置Gson的版本号GsonBuilder().setVersion(1.0):
private String twelve() {
Gson gson2 = new GsonBuilder().setVersion(1.0).create();
GsonBuilderBeanThree gsonBuilderBeanThree = new GsonBuilderBeanThree("144", "123");
return gson2.toJson(gsonBuilderBeanThree);
}
结果为:
可以看到只有username,因为我们设置版本为1.0,而password是版本1.1的,所以不会被序列化,那如果设置版本为1.1又会怎么样的?
看看结果:发现两个都出来了,说明低版本的数包含在高版本中的
再来看看反序列化,同样设置版本为1.0:
private String twelve() {
Gson gson2 = new GsonBuilder().setVersion(1.0).create();
String showString = "";
String jsonString = "{'username':'144','password':'123'}";
<span style="white-space:pre"> </span>showString += "json:" + jsonString + "\n解析后的数据:\n";
GsonBuilderBeanThree beanThree = gson2.fromJson(jsonString, GsonBuilderBeanThree.class);
showString += beanThree.toString();
showString += "----------------------\n";
return showString;
}
结果为:
可以看到password为null,原因是我设置版本为1.0,而password为1.1