您的位置:首页 > 其它

Gson进阶学习

2016-04-06 19:53 399 查看
在上一篇中,主要研究了其基本的用法,本篇将总结Gson的一些高级技能。

1、 @SerializedName 注解的使用

@SerializedName 注解是属性重命名的方法,举例说明:

Android一般使用驼峰式命名,但如果此时和我们进行数据交互的后台是PHP工程师,那我们往往将会得到下划线分割的方式进行命名的数据,比如:

Android开发希望的json数据是:

{"name":"小明","homeAddress":"中国xxxxxxxxxx","age":16,"sex":true}
但PHP习惯返回的数据是:

{"name":"小明","home_address":"中国xxxxxxxxxx","age":16,"sex":true}
这时就需要用到@SerializedName 注解,方法如下:

在实体类中通过如下代码进行注解

@SerializedName("home_address")
public String homeAddress;
此时就可以通过反射正确的解析json数据。

若出现命名混乱,后台又不愿意改,比如:

{"name":"小明","home_address":"中国xxxxxxxxxx","age":16,"sex":true}
{"name":"小明","homeaddress":"中国xxxxxxxxxx","age":16,"sex":true}
{"name":"小明","home":"中国xxxxxxxxxx","age":16,"sex":true}



可以通过如下方式进行调整:

@SerializedName(value = "homeAddress", alternate = {"home", "home_address","homeaddress"})
public String homeAddress;
此时不管出现的是homeAdress、home、home_adress或者homeadress都可以正确的解析;

2、显示Null的值

正常情况下:

User user=new User("小明",true,16,null);
String userJson = gson.toJson(user);
Log.i(TAG,userJson);//{"name":"小明","age":16,"sex":true}
若此时想要显示

"homeAddress":null

需要进行如下配置:

Gson gson = new GsonBuilder()
.serializeNulls()
.create();
此时打印结果为:

{"name":"小明","homeAddress":null,"age":16,"sex":true}


3、其他关于序列化的控制(不仅仅只包含列举的,这些只是常用的)

<pre name="code" class="java">Gson gson = new GsonBuilder()
.disableInnerClassSerialization()
.setDateFormat("yyyy-MM-dd")//序列化和反序化时将时间以此形式输出
.disableHtmlEscaping()//html标签不转义
.create();









4、注解@Expose的使用

简单来说,@Expose控制对象中的参数是否需要序列化和反序列化,其中:

@Expose(deserialize = true,serialize = true) //序列化和反序列化都都生效
@Expose(deserialize = true,serialize = false) //反序列化时生效
@Expose(deserialize = false,serialize = true) //序列化时生效
@Expose(deserialize = false,serialize = false) // 和不写一样


通过代码来解释用法:

public class User {
@Expose(deserialize = false,serialize = true)
private String name;//序列化时生效
private boolean sex; private int age;
@Expose(deserialize = false,serialize = false)
private String homeAddress;// 和不写一样,不管是序列化还是反序列化都和正常使用一样
}






此时,Gson必须通过如下的方式进行实例化:
Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();


5、@Since(int i)和@Until(int i)的用法

@Since(int i)和@Until(int i)是一种版本控制,当版本号大于Since的值时,会解析出该字段,否则不会解析出来,当版本号小于Until的时会解析出来该字段,否则不会。看代码:

public class User {
@Since(3)
private String name;
private boolean sex;
private int age;
@Until(5)
private String homeAddress;
}








解析代码:

Gson gson = new GsonBuilder().setVersion(int version).create();
结果分析:

若version<3 则解析结果为:{"homeAddress":“中国xxxxxxxx”,"age":16,"sex":true}

若version>=3并且version<5 则解析结果为:{"name":"小明","homeAddress":“中国xxxxxxxx”,"age":16,"sex":true}

若version>=5 则解析结果为:{"name":"小明","age":16,"sex":true}

其实范围可以概括为,Until之前Since之后;

6、通过访问修饰符控制序列化和反序列化

访问修饰符包括:public、private、protected、static 、final等,注意:static 会自动被排除。

通过代码解释:

<pre name="code" class="java">public class User {
private String name;
public boolean sex;
static int age;
final String homeAddress;
}




Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.FINAL,Modifier.PRIVATE)
.create();
System.out.println(gson.toJson(user));
// 结果:{"sex":true}


7、TypeAdapter的使用

TypeAdapter 是Gson的一个抽象类,用于接管某种类型的序列化和反序列化过程。

public abstract class TypeAdapter<T> {
public abstract void write(JsonWriter out, T value) throws IOException;
public abstract T read(JsonReader in) throws IOException;
}
使用示例基本类型:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Integer.class, new TypeAdapter<Integer>() {
@Override
public void write(JsonWriter out, Integer value) throws IOException {
out.value(String.valueOf(value));
}
@Override
public Integer read(JsonReader in) throws IOException {
try {
return Integer.parseInt(in.nextString());
} catch (NumberFormatException e) {
return -1;
}
}
})
.create();
使用示例自定义类型:

<pre name="code" class="java"><pre name="code" class="java">Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class, new UserTypeAdapter())
.create();
UserTypeAdapter的定义:
public class UserTypeAdapter extends TypeAdapter<User> {

@Override
public void write(JsonWriter out, User value) throws IOException {
out.beginObject();
out.name("name").value(value.name);
out.name("age").value(value.age);
out.name("sex").value(value.sex);
out.name("homeAdress").value(value.homeAdress);
out.endObject();
}
@Override
public User read(JsonReader in) throws IOException {
User user = new User();
in.beginObject();
while (in.hasNext()) {
switch (in.nextName()) {
case "name": user.name = in.nextString(); break;
case "age": user.age = in.nextInt(); break;
case "home": case "home_address": case "homeAddress": user.homeAddress = in.nextString(); break;
} }
in.endObject();
return user; }
}










8、JsonSerializer与JsonDeserializer的使用

如果你已经学会了TypeAdapter的使用,那么你就已经回使用这两个方法,他们唯一的区别在于TypeAdapter同时接管序列化和反序列化而JsonSerializer只接管序列化JsonDeserializer只接管反序列化。

9、@JsonAdapter注解的使用

该注解必须配合TypeAdpater,JsonSerializer或JsonDeserializer中的一个使用,其中是不需要

Gson gson = new GsonBuilder()

.registerTypeAdapter(User.class, new UserTypeAdapter())

.create();

直接Gson gson = new Gson();既可以将类似UserTypeAdapter的序列化和反序列化规则用于注解的类,使用示例:

@JsonAdapter(UserTypeAdapter.class)
public class User {
private String name;//序列化时生效
private boolean sex; private int age;
private String homeAddress;// 和不写一样,不管是序列化还是反序列化都和正常使用一样
}






到此,就已经基本总结完了Gson几乎全部用法,当然,肯定还有些遗漏,但常见的方法大概就这些了。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: