解析列表数据时如遇到后台数据传值为 "" 解决方式
public class BookDeserializer implements JsonDeserializer<Book>{
@Override
public Book deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
...
JsonElement jsonAuthors = jsonObject.get("authors");
if(jsonAuthors.isJsonArray()){
...
book.setAuthors(authors);
}else{
book.setAuthors(null);
}
...
}
}
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Book.class, new BookDeserializer());
...
Gson gson = gsonBuilder.create();
TypeAdapter的工作原理分析
JsonParser final类,解析成JsonElement对象(可以解析String串、Reader输入流、JsonReader输入流)
Stream.parser(JsonReader reader){...}
TypeAdapter.JSON_ELEMENT.reader(reader){...}
// 递归调用read方法将json串封装成JsonElement对象供我们使用
public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
/****
*该方法的主要作用就是让json串封装成你希望的对象,在这里是把json串
*/
@Override public JsonElement read(JsonReader in) throws IOException {
//调用peek()方法对json传进行读取和解析,并返回对应的JsonToke类型
switch (in.peek()) {
case STRING://如果是字符类型,封装并返回之
return new JsonPrimitive(in.nextString());
case NUMBER://数字类型,例如double,long,int
String number = in.nextString();
return new JsonPrimitive(new LazilyParsedNumber(number));
case BOOLEAN://boolean 类型:true or false
return new JsonPrimitive(in.nextBoolean());
case NULL://null
in.nextNull();
return JsonNull.INSTANCE;
case BEGIN_ARRAY://数组类型
//解析此数组,并添加到array中去
JsonArray array = new JsonArray();
in.beginArray();
//循环遍历数组,并调用read方法解析成JsonElement对象,添加到array中去
while (in.hasNext()) {
array.add(read(in));
}
in.endArray();
return array;//返回之
case BEGIN_OBJECT://如果只json对象,例如{"name":"value"}
JsonObject object = new JsonObject();
in.beginObject();
//解析该json对象,并获取name 和value放入object中
//注意value可能是JsonElement,所以要调用read(in)
while (in.hasNext()) {
object.add(in.nextName(), read(in));
}
in.endObject();
return object;
case END_DOCUMENT:
case NAME:
case END_OBJECT:
case END_ARRAY:
default:
throw new IllegalArgumentException();
}
}
}
// TypeAdapter抽象类解析json串为指定对象
/***
*匿名内部类的完美应用
**/
public final TypeAdapter<T> nullSafe() {
return new TypeAdapter<T>() {
@Override public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
TypeAdapter.this.write(out, value);
}
}
@Override public T read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
return TypeAdapter.this.read(reader);
}
};
}
Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class,
new TypeAdapter<Foo>() {
public Foo read(JsonReader in) throws IOException {
// read a Foo from in and return it
}
public void write(JsonWriter out, Foo src) throws IOException {
// write src as JSON to out
}
}.nullSafe()).create();
fromJson(String,Class)–>fromJson(String,Type) (Type包含了class的报名和类名 class package.className)–>fromJson(Reader,Type)–>fromJson(JsonReader,Type);最终调用了fromJson(Jsonreader,Type)
自定义Adapter要让Gson使用,registerTypeAdapter,注册
通过GsonBuilder注册TypeAdapter,并把TypeAdapter封装成TypeAdpterFactory对象;
将封装成的TypeAdapterFactory通过GsonBuilder的create传入Gson对象中并返回;
调用gson.fromJson方法,调用getTypeAdapter方法返回你自定义的Adapter,并调用其reader方法进行处理。
JsonDeserializer的工作方式
将JsonDesrializer封装成TypeAdapterFactory;
在Factory的create方法 返回TypeAdapter的时候,需要再次将JsonDesrializer封装成TypeAdapter;
然后在Gson的getTypeAdapter 方法,返回封装过后的TypeAdapter,并调用read方法;
JsonDesrializer在TypeAdapter起到代理的作用,在reader方法执行的时候实际上调用的是JsonDesrializer的deserializer方法;
Gson解析原理
如果是通过GsonBuilder创建的Gson对象,那么就用自定义的TyperAdapter来完成json的解析;
如果是通过new Gson()创建的Gson对象,那么就用Java反射机制来完成json的解析。
通过Gson的factories(List) 这个对象add TypeAdapterFactory的顺序来控制的!当是用第一种方式来创建Gson对象的时候,把自定一个TypeAdapter或者TypeAdapterFactory添加在factories靠前的位置,然后在getAdapter方法中遍历factories的每一个TypeAdapterFactory,如果当前循环中的TypeAdapterFactory.create 返回的TypeAdapter!=null,就返回该Adapter退出了factories的遍历.因为自定义的TypeAdapter位置在factories中靠前这样就优先与ReflectiveTypeAdapterFactory 遍历到,所以就避免了用Gson的反射机制来解析json了。
Gson的反射解析机制
Gson解析成Java对象:①注册TypeAdapter;②将TypeAdapter封装成TypeAdapterFactory,加至列表factories;③fromJson,getAdapter,factory的create方法创建TypeAdapter;④Typeadapter的read方法完成转换
对于每一个Java的基本类型或者集合类型,Gson都提供了与之相对应的TypeAdapter类型(如CHARACTER_FACTORY)