Gson setDateFormat thows日期为空时出现异常

Gson setDateFormat thows日期为空时出现异常,date,gson,kotlin,Date,Gson,Kotlin,我已将我的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.NullPointerExceptio

我已将我的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库中的错误?

我真的很惊讶
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()
这包括以下测试:

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)
}

如果有其他人遇到这种情况,则问题出现在Gson的2.8.1版中。返回到2.8.0或前进到2.8.2都可以修复此问题。如果您仍停留在2.8.1上,则此错误报告中有详细说明:

private Gson getGson(){
//获取DefaultDateTypeAdatpter实例的技巧
//创建Gson的第一个实例
Gson Gson=new GsonBuilder()
.setDateFormat(日期格式完成)
.create();
//获取日期适配器
TypeAdapter-dateTypeAdapter=gson.getAdapter(Date.class);
//确保DateTypeAdapter是空安全的
TypeAdapter-safeDateTypeAdapter=dateTypeAdapter.nullSafe();
//构建最终的安全Gson实例
返回新的GsonBuilder()
.registerTypeAdapter(Date.class,safeDateTypeAdapter)
.create();
}

我回答了自己的问题,但每一条评论/反馈/备选方案/改进都非常受欢迎。噢,谢谢,截止日期,我没有发现相关问题:)
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)
}
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();
}