2017-10-23 3 views
2

ich meine Gson Instanz wie gebaut haben:Gson setDateFormat thows Ausnahme, wenn Datum ist null

val DATE_FORMAT_MASK = "yyyy-MM-dd'T'HH:mm:ssZ" 

val gson = GsonBuilder() 
     .setDateFormat(DATE_FORMAT_MASK) 
     .create() 

Diese Arbeit richtig, bis ich die Serialisierung eines Null-Datum

gson.toJson(null, Date::class.java) 

Dann führen erhalte ich die folgende Ausnahme:

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) 

Wie kann ich mit dieser Situation umgehen?

Kann ein Fehler in der Gson-Bibliothek sein?

+0

ich meine eigene Frage beantworten, aber jeder Kommentar/Feedback/Alternative/Verbesserung sind sehr willkommen – crgarridos

Antwort

3

Ich erstaunte wirklich, dass setDateFormat nicht Null Serialisierung behandelt. Ich glaube, Sie sind gezwungen, Typ Adapter zu implementieren:

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

Wo toDate und toString sind:

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

Diese Abdeckung te folgender Test:

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