6 votes

Adaptateur Moshi LocalDateTime avec format multiple

Par défaut, ThreeTenABP.LocalDateTime est converti en

{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}

Je peux écrire un adaptateur pour supporter la chaîne de date ISO. 2018-04-10T03:45:26.009

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

Comment puis-je écrire un adaptateur qui peut supporter les deux formats (fromJson)

  • {"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}
  • 2018-04-10T03:45:26.009

En plus d'identifier le format utilisé dans fromJson Je suis curieux de savoir comment Moshi effectue en interne les opérations toJson/fromJson pour LocalDateTime.

7voto

Jesse Wilson Points 8455

Vous devrez utiliser JsonReader.peek() pour déterminer le format du JSON entrant, et agir en conséquence.

Installez d'abord un adaptateur qui convertit LocalDateTime à une chaîne de caractères. Cet adaptateur doit utiliser une annotation qualificative.

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

Créez ensuite l'adaptateur de chaîne. Cela devrait être simple, et pourrait être délégué à l'adaptateur Rfc3339DateJsonAdapter intégré de Moshi.

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

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

Enfin, créez un adaptateur qui délègue soit à l'adaptateur intégré de Moshi (celui-là utilisera {...} ) ou à votre adaptateur de chaîne. Celui-ci préfère le format string, mais vous pouvez faire ce que vous voulez.

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

Cela fonctionne parce que Moshi vous permet de déclarer plusieurs JsonAdapter aux arguments de l @ToJson y @FromJson et ces arguments peuvent être annotés.

Elle s'appuie également sur la manière dont cette fonctionnalité fonctionne si les types sont identiques. Ici, nous faisons un JsonAdapter<LocalDateTime> en déléguant à un autre JsonAdapter<LocalDateTime> . Lorsque les types sont les mêmes, Moshi utilise ses nextAdapter() pour la composition.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X