- Android Gson TypeAdaper 与 JsonSerializer/JsonDeserializer 的使用
- TypeAdapter
- 概述
- 使用TypeAdapter
- 处理简洁的JSON
- 处理嵌套数据
- JsonSerializer & JsonDeserializer
- 概述
- 使用JsonSerializer & JsonDeserializer
- @JsonAdapter
- TypeAdapterFactory
- TypeAdapter是一个泛型抽象类,提供两个抽象方法write()方法和read()方法,用于处理序列化和反序列化的过程。
- TypeAdapter直接使用流来解析数据,极大程度提高了解析效率。
使用TypeAdapter操作JSON字符串,序列时,需要将Java中的address数组转为字符串;反序列化时,需要将JSON字符串中的address字段转为Java数组。
创建Person实体类
class Person {
private String name;
private int age;
private String[] address;
//省略构造函数、getter/setter、toString()方法
}
定义PersonTypeAdapter类
class PersonTypeAdapter extends TypeAdapter{ //反序列化 @Override public Person read(JsonReader in) throws IOException { final Person person = new Person(); in.beginObject(); while (in.hasNext()) { switch (in.nextName()) { case "name": person.setName(in.nextString()); break; case "age": person.setAge(in.nextInt()); break; case "address": in.beginArray(); final ArrayList addressList = new ArrayList<>(); while (in.hasNext()) { addressList.add(in.nextString()); } person.setAddress(addressList.toArray(new String[addressList.size()])); in.endArray(); break; } } in.endObject(); return person; } //序列化 @Override public void write(JsonWriter out, Person person) throws IOException { out.beginObject(); out.name("name").value(person.getName()); out.name("age").value(person.getAge()); out.name("address").beginArray(); for (String item : person.getAddress()) { out.value(item); } out.endArray(); out.endObject(); } }
使用
{"name":"小白","age":18,"address":["广东省","广州市","黄埔区"]}
Gson gson = new GsonBuilder()
.registerTypeAdapter(Person.class, new PersonTypeAdapter())
.create();
//序列化
Person p1 = new Person("小白", 18, new String[]{"广东省", "广州市", "黄埔区"});
String jsonStr = gson.toJson(p1);
System.out.println(jsonStr);
//{"name":"小白","age":18,"address":["广东省","广州市","黄埔区"]}
//反序列化
String json = getJson();
Person p2 = gson.fromJson(json, Person.class);
System.out.println(p2);
//Person{name='小白', age=18, address=[广东省, 广州市, 黄埔区]}
处理简洁的JSON
序列化时,需要将Java对象转为JSON数组;反序列化时,需要将JSON数组转为指定的Java对象。
定义PersonTypeAdapter
class PersonTypeAdapter extends TypeAdapter{ //反序列化 @Override public Person read(JsonReader in) throws IOException { final Person person = new Person(); in.beginArray(); person.setName(in.nextString()); person.setAge(in.nextInt()); final ArrayList addressList = new ArrayList<>(); while (in.hasNext()) { addressList.add(in.nextString()); } person.setAddress(addressList.toArray(new String[addressList.size()])); in.endArray(); return person; } //序列化 @Override public void write(JsonWriter out, Person person) throws IOException { out.beginArray(); out.value(person.getName()); out.value(person.getAge()); for (String item : person.getAddress()) { out.value(item); } out.endArray(); } }
JSON数据
["小明",18,"广东省","广州市","黄浦区"]
使用
Gson gson = new GsonBuilder()
.registerTypeAdapter(Person.class, new PersonTypeAdapter())
.create();
//反序列化
String json = getJson();
Person p1 = gson.fromJson(json, Person.class);
System.out.println(p1);
//Person{name='小明', age=18, address=[广东省, 广州市, 黄浦区]}
//序列化
Person p2 = new Person("小明", 18, new String[]{"广东省", "广州市", "黄浦区"});
String jsonStr = gson.toJson(p2);
System.out.println(jsonStr);
//["小明",18,"广东省","广州市","黄浦区"]
处理嵌套数据
对象嵌套对象的数据结构:
{
"name":"小明",
"age":18,
"addressList":[
{
"id":110,
"addressName":"广东省"
},
{
"id":220,
"addressName":"广州市"
},
{
"id":330,
"addressName":"黄埔区"
}
]
}
定义Person类
class Person {
private String name;
private int age;
private Address[] address;
}
class Address {
private int id;
private String addressName;
}
定义PersonTypeAdapter类
class PersonTypeAdapter extends TypeAdapter{ //反序列化 @Override public Person read(JsonReader in) throws IOException { final Person person = new Person(); in.beginObject(); while (in.hasNext()) { switch (in.nextName()) { case "name": person.setName(in.nextString()); break; case "age": person.setAge(in.nextInt()); break; case "addressList": in.beginArray(); final ArrayList addressList = new ArrayList<>(); while (in.hasNext()) { in.beginObject(); final Address address = new Address(); while (in.hasNext()) { switch (in.nextName()) { case "id": address.setId(in.nextInt()); break; case "addressName": address.setAddressName(in.nextString()); break; } } addressList.add(address); in.endObject(); } person.setAddress(addressList.toArray(new Address[addressList.size()])); in.endArray(); break; } } in.endObject(); return person; } //序列化 @Override public void write(JsonWriter out, Person person) throws IOException { out.beginObject(); out.name("name").value(person.getName()); out.name("age").value(person.getAge()); out.name("addressList").beginArray(); for (Address address : person.getAddress()) { out.beginObject(); out.name("id").value(address.getId()); out.name("addressName").value(address.getAddressName()); out.endObject(); } out.endArray(); out.endObject(); } }
使用
Gson gson = new GsonBuilder()
.registerTypeAdapter(Person.class, new PersonTypeAdapter())
.create();
//序列化
Person p1 = new Person("小明", 18,
new Address[]{new Address(110, "广东省"),
new Address(220, "广州市"),
new Address(330, "黄埔区")});
String jsonStr = gson.toJson(p1);
System.out.println(jsonStr);
//{"name":"小明","age":18,"addressList":[{"id":110,"addressName":"广东省"},{"id":220,"addressName":"广州市"},{"id":330,"addressName":"黄埔区"}]}
//反序列化
String json = getJson();
Person p2 = gson.fromJson(json, Person.class);
System.out.println(p2);
//Person{name='小明', age=18, address=[Address{id=110, addressName='广东省'}, Address{id=220, addressName='广州市'}, Address{id=330, addressName='黄埔区'}]}
JsonSerializer & JsonDeserializer
概述
- TypeAdapter将序列化和反序列操作都接管了过来,可以通过JsonSerializer和JsonDeserializer只处理其中一个。
- JsonSerializer & JsonDeserializer 在解析都会利用中间件——JsonElement。
定义Person类
class Person {
private String name;
private int age;
private String[] address;
}
定义PersonTypeAdapter类
class PersonTypeAdapter implements JsonSerializer, JsonDeserializer { //反序列化 @Override public Person deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { final Person person = new Person(); JsonObject jsonObject = json.getAsJsonObject(); if (jsonObject.has("name")) { person.setName(jsonObject.get("name").getAsString()); } if (jsonObject.has("age")) { person.setAge(jsonObject.get("age").getAsInt()); } if (jsonObject.has("address")) { JsonArray jsonArray = jsonObject.getAsJsonArray("address"); ArrayList addressList = new ArrayList<>(); for (int i = 0; i < jsonArray.size(); i++) { addressList.add(jsonArray.get(i).getAsString()); } person.setAddress(addressList.toArray(new String[jsonArray.size()])); } return person; } //序列化 @Override public JsonElement serialize(Person person, Type typeOfSrc, JsonSerializationContext context) { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("name", person.getName()); jsonObject.addProperty("age", person.getAge()); JsonArray jsonArray = new JsonArray(); for (String item : person.getAddress()) { jsonArray.add(item); } jsonObject.add("address", jsonArray); return jsonObject; } }
使用
Gson gson = new GsonBuilder()
.registerTypeAdapter(Person.class, new PersonTypeAdapter())
.create();
//序列化
Person p1 = new Person("小白", 18, new String[]{"广东省", "广州市", "黄埔区"});
String jsonStr = gson.toJson(p1);
System.out.println(jsonStr);
//{"name":"小白","age":18,"address":["广东省","广州市","黄埔区"]}
//反序列化
String json = getJson();
Person p2 = gson.fromJson(json, Person.class);
System.out.println(p2);
//Person{name='小白', age=18, address=[广东省, 广州市, 黄埔区]}
@JsonAdapter
还可以使用@JsonAdapter注解,效果与registerTypeAdapter()方法基本一样,但注解的优先级高于registerTypeAdapter()方法。
@JsonAdapter(PersonTypeAdapter.class)
class Person {
private String name;
private int age;
private String[] address;
}
TypeAdapterFactory
TypeAdapterFactory 是用于创建 TypeAdapter 的工厂类,通过参数 TypeToken 来查找确定对应的 TypeAdapter,如果没有就返回 null 并由 Gson 默认的处理方法来进行序列化和反序列化操作,否则就由用户预定义的 TypeAdapter 来进行处理。
优先执行registerTypeAdapter()方法,然后在执行registerTypeAdapterFactory()方法。
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new TypeAdapterFactory() {
@Override
public TypeAdapter create(Gson gson, TypeToken type) {
if (type.getType().getTypeName().equals(Person.class.getTypeName())) {
return (TypeAdapter) new PersonTypeAdapter();
}
return null;
}
})
.create();



