Gson解析給我滿帶來(lái)了很多方便,但其實(shí),Gson可以更方便,接下來(lái)就介紹Gson的兩個(gè)特殊功能,這兩個(gè)功能也是在深入使用Gson解析中必須掌握的。它們分別是:自定義類型適配器和自定義參數(shù)適配器。
1 自定義類型適配器。
在第一章節(jié)中講到Gson對(duì)String類型的解析如下:
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
@Override
public String read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
if (peek == JsonToken.NULL) {//如果為null,直接返回
in.nextNull();
return null;
}
/* coerce booleans to strings for backwards compatibility */
if (peek == JsonToken.BOOLEAN) {//如果是bool型,則轉(zhuǎn)成String
return Boolean.toString(in.nextBoolean());
}
return in.nextString();
}
@Override
public void write(JsonWriter out, String value) throws IOException {
out.value(value);
}
};
針對(duì)如上解析。如待解析數(shù)據(jù)如下:
{
"name":"zhangsan",
"addr":"beijing",
"no":18888888888,
"others":""}
其對(duì)應(yīng)的model如下:
public class StringModel {
String name;
String addr;
String no;
String others;
}
在正常情況下,others這個(gè)字段會(huì)被解析成一個(gè)長(zhǎng)度為0的字符串,但是很多情況下,為了規(guī)范Android端數(shù)據(jù)解析,如果服務(wù)端返回""、null、NULL等數(shù)據(jù)時(shí),??解析為null。在這種情況下,就需要自定義TypeAdapter,來(lái)規(guī)范字符串的解析過(guò)程。
針對(duì)如上需求,自定義的TypeAdapter如下:
public class StringTypeAdapter extends TypeAdapter<String> {
@Override
public String read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
if (peek == JsonToken.NULL) {//如果為null,直接返回
in.nextNull();
return null;
}
/* coerce booleans to strings for backwards compatibility */
if (peek == JsonToken.BOOLEAN) {//如果是bool型,則轉(zhuǎn)成String
return Boolean.toString(in.nextBoolean());
}
String result = in.nextString();
if (TextUtils.isEmpty(result)) {
return null;
}
return result;
}
@Override
public void write(JsonWriter out, String value) throws IOException {
out.value(value);
}
}
自定義TypeAdapter的使用如下:
String jsonString = "{\n" +
"\"name\":\"zhangsan\",\n" +
"\"addr\":\"beijing\",\n" +
"\"no\":18888888888}";
Gson gson = new GsonBuilder().registerTypeAdapter(String.class, new StringTypeAdapter()).create();
StringModel stringModel = gson.fromJson(jsonString, StringModel.class);
Gson的構(gòu)建方式發(fā)生了變化,采用了GsonBuilder來(lái)生成的方式。registerTypeAdapter()專門用來(lái)注冊(cè)自定義的TypeAdapter,StringTypeAdapter只是類型自定義適配器的一個(gè)簡(jiǎn)單的例子,利用TypeAdapter,還可以實(shí)現(xiàn)很多高級(jí)的功能。關(guān)于類型自定義適配器就介紹到這。下面介紹一下Gson的第二個(gè)特殊功能自定義參數(shù)適配器。
2 自定義參數(shù)適配器
自定義參數(shù)適配器比自定義類型適配器的粒度更細(xì),它能夠精確到具體的參數(shù)。對(duì)某個(gè)待解析(待生成)的參數(shù)實(shí)現(xiàn)自定義配置。
還是以上面的數(shù)據(jù)為例:
{
"name":"zhangsan",
"addr":"beijing",
"birth":18978787,
"no":18888888888,
"others":null}
添加了一個(gè)birth字段。這個(gè)字段是long型數(shù)據(jù)。但是在客戶端使用這個(gè)數(shù)據(jù)的時(shí)候,希望他是Date類型。在正常情況下,Gson是無(wú)法做到從long型轉(zhuǎn)換成Date類型的。(注意:簡(jiǎn)單數(shù)據(jù)類型之間的轉(zhuǎn)換,Gson是默認(rèn)支持的)所以,在這種情況下自定義參數(shù)適配器就產(chǎn)生了。自定義參數(shù)適配器主要用到了JsonSerializer 和JsonDeserializer。下面以上面的為例,自定義JsonDeserializer如下:
public class DateDeserializer implements JsonDeserializer<Date> {
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
long time = jsonObject.get("birth").getAsLong();
return new Date(time);
}
}
待解析model如下:
public class StringModel {
String name;
String addr;
@JsonAdapter(DateDeserializer.class)
Date birth;
String no;
String others;
}
這樣就實(shí)現(xiàn)了參數(shù)的自定義解析,如果只是想StringModel這一個(gè)類的birth屬性實(shí)現(xiàn)自定義解析,如上實(shí)現(xiàn)已經(jīng)足夠了,如果想實(shí)現(xiàn)所有model中的birth屬性都能采用相同的自定義解析方式,那么就需要將DateDeserializer注冊(cè)到GsonBuilder中。實(shí)現(xiàn)方式如下:
Gson gson = new GsonBuilder()
.registerTypeAdapter(String.class, new StringTypeAdapter())
.registerTypeAdapter(Date.class,new DateDeserializer())
.create();
參數(shù)的自定義生成過(guò)程與之相反,這里就不一一介紹了。