首页 > 解决方案 > 使用带有改造的android反序列化日期时间字符串

问题描述

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

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


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

问候,

卫斯理。

标签: androidretrofit

解决方案


此解决方案是动态的,因此您可以在GsonUtils课堂上注册任意数量的TypeAdapter。

为此,您必须customGsonConverterFactory像这样创建自己的类:

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 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类,您可以在其中注册自定义适配器,如下所示:

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

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

Kotlin 等效的 GsonUtils 类

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

推荐阅读