使用 android 和改造反序列化日期时间字符串

Deserialize datetime string using android with retrofit

我正在尝试使用改造和在 kotlin 中定义的模型反序列化 JSON。但是我无法让它工作。我不断收到无法序列化的错误。

{
  "Id": 144007,
  "StartTime": "2020-05-14T16:38:30.753",
}


data class PickJobModel (
  @SerializedName("Id") val id: Int,
  @SerializedName("StartTime") val startTime: Date?
)

此致,

卫斯理.

val gson = GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
--
Retrofit.Builder()
                ....
                .addConverterFactory(GsonConverterFactory.create(gson))

此解决方案是动态的,因此您可以在 GsonUtils class.

中注册任意数量的 TypeAdapter

为此,您必须创建自己的 customGsonConverterFactory class,如下所示:

public class CustomGsonConverterFactory extends Converter.Factory {

    private final Gson gson;

    private CustomGsonConverterFactory(Gson gson) {
        this.gson = gson;
    }

    public static CustomGsonConverterFactory create(Gson gson) {
        if (gson == null) throw new NullPointerException("gson == null");
        return new CustomGsonConverterFactory(gson);
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonResponseBodyConverter<>(gson, adapter);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonRequestBodyConverter<>(gson, adapter);
    }
}

Kotlin 等效 CustomGsonConverterFactory class

class CustomGsonConverterFactory private constructor(private val gson: Gson) : Converter.Factory() {

    fun responseBodyConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<ResponseBody, *> {
        val adapter = gson.getAdapter<*>(TypeToken.get(type))
        return GsonResponseBodyConverter(gson, adapter)
    }

    fun requestBodyConverter(
        type: Type,
        parameterAnnotations: Array<Annotation>,
        methodAnnotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, RequestBody> {
        val adapter = gson.getAdapter<*>(TypeToken.get(type))
        return GsonRequestBodyConverter(gson, adapter)
    }

    companion object {

        fun create(gson: Gson?): CustomGsonConverterFactory {
            if (gson == null) throw NullPointerException("gson == null")
            return CustomGsonConverterFactory(gson)
        }
    }
}

创建 GsonUtils class,您可以在其中注册自定义适配器,如下所示:

public class GsonUtils {
    private static final Gson sGSON = new GsonBuilder()
            .registerTypeAdapter(Date.class, new DateDeserializer())
            .create();

    public static Gson getGson() {
        return sGSON;
    }
   }

Kotlin 等效 GsonUtils class

object GsonUtils {
    val gson = GsonBuilder()
        .registerTypeAdapter(Date::class.java, DateDeserializer())
        .create()
}

现在您必须创建客户 DateDeserializer 并像这样添加日期格式:

public class DateDeserializer implements JsonDeserializer<Date> {

    @Override
    public Date deserialize(JsonElement jsonElement, Type typeOF, JsonDeserializationContext context) throws JsonParseException {

            try {
                return new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss.SSS", Locale.US).parse(jsonElement.getAsString());
            } catch (ParseException ignored) {
            }

        throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString()
                + "\". Supported formats: " + Arrays.toString(DateUtilz.DATE_FORMATS));
    }
}

Kotlin 等效 DateDeserializer class

class CustomGsonConverterFactory private constructor(private val gson: Gson) : Converter.Factory() {

    fun responseBodyConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<ResponseBody, *> {
        val adapter = gson.getAdapter<*>(TypeToken.get(type))
        return GsonResponseBodyConverter(gson, adapter)
    }

    fun requestBodyConverter(
        type: Type,
        parameterAnnotations: Array<Annotation>,
        methodAnnotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, RequestBody> {
        val adapter = gson.getAdapter<*>(TypeToken.get(type))
        return GsonRequestBodyConverter(gson, adapter)
    }

    companion object {

        fun create(gson: Gson?): CustomGsonConverterFactory {
            if (gson == null) throw NullPointerException("gson == null")
            return CustomGsonConverterFactory(gson)
        }
    }
}

最后,添加您的 customGsonConverterFactory

Retrofit.Builder()
            ....
            .addConverterFactory(CustomGsonConverterFactory.create(GsonUtils.getGson()))