90 votes

Rétrofit GSON sérialise la date de la chaîne json en java.util.date

J'utilise la bibliothèque Retrofit pour mes appels REST. La plupart de ce que j'ai fait s'est déroulé sans problème, mais pour une raison ou une autre, j'ai des difficultés à convertir les chaînes d'horodatage JSON en chaînes d'enregistrement. java.util.Date objets. Le JSON qui arrive ressemble à ça.

{
    "date": "2013-07-16",
    "created_at": "2013-07-16T22:52:36Z",
} 

Comment puis-je dire à Retrofit ou Gson de convertir ces chaînes en java.util.Date objects ?

0voto

shiami Points 1674

Vous pouvez définir deux nouvelles classes comme ceci :

import java.util.Date;

public class MyDate extends Date {
}

et

import java.util.Date;

public class CreatedAtDate extends Date {
}

Votre POJO sera comme ceci :

import MyDate;
import CreatedAtDate;

public class Foo {
    MyDate date;
    CreatedAtDate created_at;
}

Enfin, définissez votre désérialiseur personnalisé :

public class MyDateDeserializer implements JsonDeserializer<Date> {

    public static final SimpleDateFormat sServerDateDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public MyDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
         if (json != null) {
            final String jsonString = json.getAsString();
            try {
                return (MyDate) sServerDateDateFormat.parse(jsonString);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

et

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(MyDate.class, new MyDateDeserializer());

0voto

AndrewBloom Points 71

Cela ne répond pas directement à la question posée, mais c'est à mon avis "l'état de l'art" si le codeur a toute liberté de choix sur la façon de résoudre le problème.

Tout d'abord, ce n'est pas la meilleure solution d'utiliser java.util.Date. La raison en est que ces classes n'avaient pas un comportement idéal dans certains cas particuliers et qu'elles ont été supplantées par la classe Java Instant, etc. Consultez la réponse de Basil Bourque à cette question S.O : Création d'objets Date en Kotlin pour un niveau d'API inférieur ou égal à 16

J'ai donc utilisé la classe Instant de ThreeTenABP, et en utilisant Kotlin, sur Android :

val gson = GsonBuilder().registerTypeAdapter(Instant::class.java,
    JsonDeserializer<Instant> { json: JsonElement, _: Type?, _: JsonDeserializationContext? ->
        ZonedDateTime.parse(
            json.asJsonPrimitive.asString
        ).toInstant()
    }
).create()

val retrofit = Retrofit.Builder()
    .baseUrl(baseUrl)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()

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