本篇文章是基于Gson官方使用指导(Gson User Guide)以及Gson解析的优秀外文(来自http://www.javacreed.com/ )做出的一个翻译和归纳。
博客原链接:
Gson全解析(上)
Gson全解析(中)
TypeAdapter介绍
前面的Gson全解析(上)中我们理解并分别运用了JsonSerializer和JsonDeserializer进行JSON和java实体类之间的相互转化。这里利用TypeAdapter
来更加高效的完成同样的这个功能。
之前在上一篇文中提到的JsonSerializer
和 JsonDeserializer
解析的时候都利用到了一个中间件-JsonElement
,比如下方的序列化过程。
而TypeAdapter
的使用正是去掉了这个中间层,直接用流来解析数据,极大程度上提高了解析效率。
New applications should prefer TypeAdapter, whose streaming API is more efficient than this interface’s tree API.
应用中应当尽量使用TypeAdapter
,它流式的API相比于之前的树形解析API将会更加高效。
TypeAdapter
作为一个抽象类提供两个抽象方法。分别是write()
和read()
方法,也对应着序列化和反序列化。如下图所示:
TypeAdapter实例
为了便于理解,这里还是统一一下,采用和上面一篇文章同样的例子。
Book.java
实体类:
package com.javacreed.examples.gson.part1;
public class Book {
private String[] authors;
private String isbn;
private String title;
//为了代码简洁,这里移除getter和setter方法等
}
具体序列化和反序列化的TypeAdapter
类,这里是BookTypeAdapter.java
:
package com.javacreed.examples.gson.part1;
import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
public class BookTypeAdapter extends TypeAdapter {
@Override
public Book read(final JsonReader in) throws IOException {
final Book book = new Book();
in.beginObject();
while (in.hasNext()) {
switch (in.nextName()) {
case "isbn":
book.setIsbn(in.nextString());
break;
case "title":
book.setTitle(in.nextString());
break;
case "authors":
book.setAuthors(in.nextString().split(";"));
break;
}
}
in.endObject();
return book;
}
@Override
public void write(final JsonWriter out, final Book book) throws IOException {
out.beginObject();
out.name("isbn").value(book.getIsbn());
out.name("title").value(book.getTitle());
out.name("authors").value(StringUtils.join(book.getAuthors(), ";"));
out.endObject();
}
}
同样这里设置TypeAdapter
之后还是需要配置(注册),可以注意到的是gsonBuilder.registerTypeAdapter(xxx)
方法进行注册在我们之前的JsonSerializer
和JsonDeserializer
中也有使用:
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Book.