具有多种格式的Moshi LocalDateTime适配器

时间:2018-04-10 09:59:00

标签: kotlin java-time moshi

默认情况下,ThreeTenABP.LocalDateTime转换为

entrypoint: bash -c 'SE_OPTS="-host $$HOSTNAME" /opt/bin/entry_point.sh'

我可以编写一个适配器来支持ISO日期字符串{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}

2018-04-10T03:45:26.009

如何编写可以支持这两种格式的适配器(fromJson)

  • class LocalDateTimeAdapter { @ToJson fun toJson(value: LocalDateTime): String { return FORMATTER.format(value) } @FromJson fun fromJson(value: String): LocalDateTime { return FORMATTER.parse(value, LocalDateTime.FROM) } companion object { private val FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME } }
  • {"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}

除了确定2018-04-10T03:45:26.009中使用的格式之外,我很好奇Moshi如何在内部执行toJson / fromJson for LocalDateTime

1 个答案:

答案 0 :(得分:6)

您需要使用JsonReader.peek()来确定传入JSON的格式,然后相应地采取措施。

首先安装一个将LocalDateTime转换为字符串的适配器。该适配器应使用限定符注释。

@Retention(RetentionPolicy.RUNTIME)
@JsonQualifier
@interface DateString {
}

接下来创建字符串适配器。它应该是直截了当的,可能会委托给Moshi的内置Rfc3339DateJsonAdapter。

public final class LocalDateAsStringAdapter {
  @ToJson String toJson(@DateString LocalDateTime localDateTime) {
    ...
  }

  @FromJson @DateString LocalDateTime fromJson(String string) {
    ...
  }
}

最后创建一个适配器,该适配器委托给Moshi的内置适配器(一个将使用{...})或者你的字符串适配器。这个更喜欢字符串格式,但你可以做你喜欢的事情。

public final class MultipleFormatsDateAdapter {
  @ToJson void toJson(JsonWriter writer, LocalDateTime value,
      @DateString JsonAdapter<LocalDateTime> stringAdapter) throws IOException {
    stringAdapter.toJson(writer, value);
  }

  @FromJson LocalDateTime fromJson(JsonReader reader, @DateString JsonAdapter<LocalDateTime> stringAdapter,
      JsonAdapter<LocalDateTime> defaultAdapter) throws IOException {
    if (reader.peek() == JsonReader.Token.STRING) {
      return stringAdapter.fromJson(reader);
    } else {
      return defaultAdapter.fromJson(reader);
    }
  }
}

这是有效的,因为Moshi允许您为JsonAdapter@ToJson方法声明多个@FromJson参数,并且可以对这些参数进行注释。

如果类型相同,它还依赖于此功能的工作方式。在这里,我们通过委托给另一个JsonAdapter<LocalDateTime>来制作JsonAdapter<LocalDateTime>。当类型相同时,Moshi使用其nextAdapter()特征进行合成。