使用 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();