我已将我的Gson实例构建为:
val DATE_FORMAT_MASK = "yyyy-MM-dd'T'HH:mm:ssZ"
val gson = GsonBuilder()
.setDateFormat(DATE_FORMAT_MASK)
.create()
这一功能正常,直到我执行空日期的序列化
gson.toJson(null, Date::class.java)
然后我得到以下异常:
java.lang.NullPointerException
at java.util.Calendar.setTime(Calendar.java:1770)
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:943)
at java.text.SimpleDateFormat.format(SimpleDateFormat.java:936)
at java.text.DateFormat.format(DateFormat.java:345)
at com.google.gson.DefaultDateTypeAdapter.write(DefaultDateTypeAdapter.java:88)
at com.google.gson.DefaultDateTypeAdapter.write(DefaultDateTypeAdapter.java:40)
at com.google.gson.Gson.toJson(Gson.java:669)
at com.google.gson.Gson.toJson(Gson.java:648)
at com.google.gson.Gson.toJson(Gson.java:603)
我如何处理这种情况?
可能是Gson库中的一个错误?
答案 0 :(得分:3)
我真的很惊讶setDateFormat
没有处理空序列化。我认为你被迫实现类型适配器:
val gson = GsonBuilder()
//.setDateFormat(DATE_FORMAT_MASK)
.registerTypeAdapter(Date::class.java, JsonSerializer<Date> { date: Date?, type, context ->
val parsed = date?.toString(DATE_FORMAT_MASK)
if(parsed == null) null
else context?.serialize(parsed)
})
.registerTypeAdapter(Date::class.java, JsonDeserializer<Date> { json: JsonElement?, type, context ->
json?.asString?.toDate(DATE_FORMAT_MASK)
})
.create()
toDate
和toString
的位置:
fun Date.toString(mask: String): String? {
try {
val simpleDateFormat = SimpleDateFormat(mask, Locale.getDefault())
return simpleDateFormat.format(this)
} catch (ignored: Exception) {
return null
}
}
fun String.toDate(mask: String): Date? {
return try {
val simpleDateFormat = SimpleDateFormat(mask, Locale.getDefault())
simpleDateFormat.parse(this)
} catch (ignored: Exception) {
null
}
}
以下测试包括:
data class DateWrapper(val date: Date?)
@Test fun date_serialization() {
val deserializedDate = gson.fromJson("\"2017-10-23T12:48:43+0200\"", Date::class.java)
assertNotNull(deserializedDate)
val deserializedNullDate = gson.fromJson("null", Date::class.java)
assertNull(deserializedNullDate)
val deserializedNullDate2 = gson.fromJson("", Date::class.java)
assertNull(deserializedNullDate2)
val deserializedDateWrapper = gson.fromJson("{date: null}", DateWrapper::class.java)
assertNull(deserializedDateWrapper.date)
val deserializedDateWrapper2 = gson.fromJson("{date: \"\"}", DateWrapper::class.java)
assertNull(deserializedDateWrapper2.date)
val deserializedDateWrapper3 = gson.fromJson("{}", DateWrapper::class.java)
assertNull(deserializedDateWrapper3.date)
val serializedDate = gson.toJson(Date(), Date::class.java)
assertNotNull(serializedDate)
val serializedNullDate = gson.toJson(null, Date::class.java)
assertEquals("null", serializedNullDate)
val date = Date()
val serializedDateWrapper = gson.toJson(DateWrapper(date), DateWrapper::class.java)
assertNotNull(serializedDateWrapper)
val serializedDateWrapper2 = gson.toJson(DateWrapper(null), DateWrapper::class.java)
assertNotNull(serializedDateWrapper2)
}
答案 1 :(得分:1)
如果其他任何人遇到此问题,则Gson 2.8.1版中存在此问题。回到2.8.0或前进到2.8.2都可以解决此问题。如果您坚持使用2.8.1,此错误报告中将详细介绍another workaround:https://github.com/google/gson/issues/1096
private Gson getGson() {
// Trick to get the DefaultDateTypeAdatpter instance
// Create a first instance a Gson
Gson gson = new GsonBuilder()
.setDateFormat(DATE_FORMAT_COMPLETE)
.create();
// Get the date adapter
TypeAdapter<Date> dateTypeAdapter = gson.getAdapter(Date.class);
// Ensure the DateTypeAdapter is null safe
TypeAdapter<Date> safeDateTypeAdapter = dateTypeAdapter.nullSafe();
// Build the definitive safe Gson instance
return new GsonBuilder()
.registerTypeAdapter(Date.class, safeDateTypeAdapter)
.create();
}