本文内容大多基于官方文档和网上前辈经验总结,经过个人实践加以整理积累,仅供参考。
TypeAdapter 是 Gson 2.0 开始的一个抽象类,用于接管某种类型的序列化和反序列化过程
TypeAdapter 的两个主要方法
public abstract class TypeAdapter<T> {
public abstract void write(JsonWriter out, T value) throws IOException;
public abstract T read(JsonReader in) throws IOException;
}
示例
(1) POJO
public class User {
private String name;
private String phoneNumber;
public User() {}
public User(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return "User [name=" + name + ", phoneNumber=" + phoneNumber + "]";
}
}
(2) TypeAdapter 接口类
class UserTypeAdapter extends TypeAdapter<User> {
@Override
public User read(JsonReader reader) throws IOException {
User user = new User();
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "name":
case "custom-name":
case "adapter-name":
user.setName(reader.nextString());
break;
case "phone":
case "custom-phone":
case "adapter-phone":
user.setPhoneNumber(reader.nextString());
break;
default:
break;
}
}
reader.endObject();
return user;
}
@Override
public void write(JsonWriter writer, User user) throws IOException {
writer.beginObject();
writer.name("adapter-name").value(user.getName());
writer.name("adapter-phone").value(user.getPhoneNumber());
writer.endObject();
}
}
(3) 测试代码
@Test
public void test() throws IOException {
User user = new User("UserX", "160");
Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class, new UserTypeAdapter())
.create();
System.out.println(gson.toJson(user));
String userStr = "{\"name\":\"Name\",\"phone\":\"151\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"custom-name\":\"CustomName\",\"custom-phone\":\"152\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"adapter-name\":\"AdapterName\",\"adapter-phone\":\"153\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"name\":\"nameX\",\"adapter-phone\":\"154\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"adapter-name\":\"nameY\",\"phone\":\"155\"}";
System.out.println(gson.fromJson(userStr, User.class));
}
测试结果:
Gson 还提供了一个类注解 @JsonAdapter,如果使用此注释则每次生成 Gson 对象时不用再注册类型适配器,即不用再调用 GsonBuilder.registerTypeAdapter
示例
更新 POJO
@JsonAdapter(UserTypeAdapter.class)
public class User {
private String name;
private String phoneNumber;
public User() {}
public User(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return "User [name=" + name + ", phoneNumber=" + phoneNumber + "]";
}
}
测试代码:
@Test
public void test() throws IOException {
User user = new User("UserX", "160");
Gson gson = new Gson();
System.out.println(gson.toJson(user));
String userStr = "{\"name\":\"Name\",\"phone\":\"151\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"custom-name\":\"CustomName\",\"custom-phone\":\"152\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"adapter-name\":\"AdapterName\",\"adapter-phone\":\"153\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"name\":\"nameX\",\"adapter-phone\":\"154\"}";
System.out.println(gson.fromJson(userStr, User.class));
userStr = "{\"adapter-name\":\"nameY\",\"phone\":\"155\"}";
System.out.println(gson.fromJson(userStr, User.class));
}
运行结果: