Android Gson TypeAdaper 与 JsonSerializer/JsonDeserializer 的使用
TypeAdapter
概述
- TypeAdapter是一个泛型抽象类,提供两个抽象方法
write() 方法和read() 方法,用于处理序列化和反序列化的过程。 - TypeAdapter直接使用流来解析数据,极大程度提高了解析效率。
使用TypeAdapter
使用TypeAdapter操作JSON字符串,序列时,需要将Java中的address数组转为字符串;反序列化时,需要将JSON字符串中的address字段转为Java数组。
创建Person实体类
class Person {
private String name;
private int age;
private String[] address;
}
定义PersonTypeAdapter类
class PersonTypeAdapter extends TypeAdapter<Person> {
@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<String> 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);
String json = getJson();
Person p2 = gson.fromJson(json, Person.class);
System.out.println(p2);
处理简洁的JSON
序列化时,需要将Java对象转为JSON数组;反序列化时,需要将JSON数组转为指定的Java对象。
定义PersonTypeAdapter
class PersonTypeAdapter extends TypeAdapter<Person> {
@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<String> 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 p2 = new Person("小明", 18, new String[]{"广东省", "广州市", "黄浦区"});
String jsonStr = gson.toJson(p2);
System.out.println(jsonStr);
处理嵌套数据
对象嵌套对象的数据结构:
{
"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<Person> {
@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<Address> 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);
String json = getJson();
Person p2 = gson.fromJson(json, Person.class);
System.out.println(p2);
JsonSerializer & JsonDeserializer
概述
TypeAdapter 将序列化和反序列操作都接管了过来,可以通过JsonSerializer 和JsonDeserializer 只处理其中一个。- JsonSerializer & JsonDeserializer 在解析都会利用中间件——JsonElement。
使用JsonSerializer & JsonDeserializer
定义Person类
class Person {
private String name;
private int age;
private String[] address;
}
定义PersonTypeAdapter类
class PersonTypeAdapter implements JsonSerializer<Person>, JsonDeserializer<Person> {
@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<String> 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);
String json = getJson();
Person p2 = gson.fromJson(json, Person.class);
System.out.println(p2);
@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 <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getType().getTypeName().equals(Person.class.getTypeName())) {
return (TypeAdapter<T>) new PersonTypeAdapter();
}
return null;
}
})
.create();
|