1

在 Android 上,使用Retrofit 2及其Gson 转换器,您可以将 ISO 8601 字符串"2016-10-26T11:36:29.742+03:00"(在后端的 JSON 响应中)直接映射到java.util.DatePOJO 中的字段。这开箱即用。

现在,我正在使用ThreeTenABP库(它提供了 java.time 类的反向移植版本),我想知道是否可以将 ISO 时间戳字符串直接映射到更好、更现代的类型,例如OffsetDateTimeor ZonedDateTime

在大多数情况下(想想服务器端的 Java 8),显然,从 " 2016-10-26T11:36:29.742+03:00" 转换为OffsetDateTimeorZonedDateTime会很简单,因为日期字符串包含时区信息。

我尝试在我的 POJO 中同时使用OffsetDateTimeand ZonedDateTime(而不是 Date),但至少开箱即用它不起作用。如果您可以使用 Retrofit 2 在 Android 上干净地做到这一点,有什么想法吗?

依赖项:

compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

compile 'com.jakewharton.threetenabp:threetenabp:1.0.4'

构建改造实例:

new Retrofit.Builder()
// ...
.addConverterFactory(GsonConverterFactory.create())
.build();
4

2 回答 2

3

你可以:

  1. 创建一个类型适配器,实现JsonDeserializer<T>JSON 文字并将其转换为您想要的任何 ThreeTen 类型。示例LocalDate

    @Override
    public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        try {
            if (typeOfT == LocalDate.class) {
                return LocalDate.parse(json.getAsJsonPrimitive().getAsString(), DateTimeFormatter.ISO_DATE);
            }
        } catch (DateTimeParseException e) {
            throw new JsonParseException(e);
        }
        throw new IllegalArgumentException("unknown type: " + typeOfT);
    }
    

    为您想要的 ThreeTen 类型实现类似的操作留作练习。

  2. GsonBuilder在构建Gson实例时注册类型适配器:

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(LocalDate.class, new YourTypeAdapter());
    Gson gson = gsonBuilder.create();
    
  3. 注册Gson实例Retrofit.Builder

    builder.addConverterFactory(GsonConverterFactory.create(gson));
    
  4. 使用 Retrofit 的 Gson 模型类中的 ThreeTen 类型。

同样,如果您想将 ThreeTen 类型序列化为 JSON,也可以JsonSerializer在您的类型适配器中实现。

于 2017-01-05T13:31:41.403 回答
1

我创建了一个小型库,它完全按照 laalto 在他的回答中提出的建议,随意使用它:Android Java Time Gson Deserializers

于 2018-01-24T15:13:28.697 回答