使用 Gson 的自定義 JSON 反序列化器
想象一下,你在所有響應中都有一些自定義格式的日期,例如/
Date(1465935152)/
,並且你希望應用一般規則將所有 Json 日期反序列化為 java Date
例項。在這種情況下,你需要實現自定義 Json 反序列化器。
json 的例子:
{
"id": 1,
"created_on": "Date(1465935152)",
"updated_on": "Date(1465968945)",
"name": "Oleksandr"
}
假設我們在下面有這個類:
class User {
@SerializedName("id")
long id;
@SerializedName("created_on")
Date createdOn;
@SerializedName("updated_on")
Date updatedOn;
@SerializedName("name")
String name;
}
自定義解串器:
class DateDeSerializer implements JsonDeserializer<Date> {
private static final String DATE_PREFIX = "/Date(";
private static final String DATE_SUFFIX = ")/";
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String dateString = json.getAsString();
if (dateString.startsWith(DATE_PREFIX) && dateString.endsWith(DATE_SUFFIX)) {
dateString = dateString.substring(DATE_PREFIX.length(), dateString.length() - DATE_SUFFIX.length());
} else {
throw new JsonParseException("Wrong date format: " + dateString);
}
return new Date(Long.parseLong(dateString) - TimeZone.getDefault().getRawOffset());
}
}
用法:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateDeSerializer())
.create();
String json = "....";
User user = gson.fromJson(json, User.class);
使用日期型別序列化和反序列化 Jackson JSON 字串
例如,這也適用於你希望 Gson Date 轉換與 Jackson 相容的情況。
傑克遜通常將日期序列化為自紀元以來的毫秒,而 Gson 使用像 Aug 31, 2016 10:26:17
這樣的可讀格式來表示日期。當你嘗試反序列化 Jackson 格式的日期時,這會導致 Gson 中的 JsonSyntaxExceptions。
為了避免這種情況,你可以新增自定義序列化程式和自定義反序列化程式:
JsonSerializer<Date> ser = new JsonSerializer<Date>() {
@Override
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext
context) {
return src == null ? null : new JsonPrimitive(src.getTime());
}
};
JsonDeserializer<Date> deser = new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
return json == null ? null : new Date(json.getAsLong());
}
};
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, ser)
.registerTypeAdapter(Date.class, deser)
.create();