2

TL;博士:

我的问题是:

1 - 我怎样才能Adapter"timestamp": 1515375392.225to做一个ZonedDateTime

2-根据文档,如果我需要 moshi 对象来获取此适配器,如何List<Report>moshi对象中注册适配器?Builder


我的 JSON 字符串具有以下结构:

[
  {
    "id": 0,
    "location": {
      "latitude": -22.967049,
      "longitude": -43.19096
    },
    "timestamp": 1515375392.225
  },
  {
    "id": 0,
    "location": {
      "latitude": -22.965845,
      "longitude": -43.191102
    },
    "timestamp": 1515375392.225
  },
.......
}]

是由 进行的timestamp自动转换Jackson JavaTimeModule,它以十进制数的形式将 a 转换ZonedDateTime为 a ,表示 a和a 。timestamp StringsecondsnanosecondsInstant

为了解析 JSON timestamp String,我制作了以下Moshi适配器:

public class ZonedDateTimeAdapter {
    @FromJson ZonedDateTime fromJson(String timestamp) {
        int decimalIndex = timestamp.indexOf('.');
        long seconds = Long.parseLong(timestamp.substring(0, decimalIndex));
        long nanoseconds = Long.parseLong(timestamp.substring(decimalIndex));

        return Instant.ofEpochSecond(seconds, nanoseconds).atZone(ZoneId.systemDefault());
    }

    @ToJson String toJson(ZonedDateTime zonedDateTime) {
        Instant instant = zonedDateTime.toInstant();
        return instant.getEpochSecond() + "." + instant.getNano();
    }
}

然后我将此适配器注册为:

Type type = Types.newParameterizedType(List.class, Report.class);

Moshi moshi = new Moshi.Builder().add(new ZonedDateTimeAdapter()).build();
JsonAdapter<List<Report>> reportAdapter = moshi.adapter(type);

retrofit = new Retrofit.Builder()
                       .baseUrl(BASE_URL)
                       .addConverterFactory(MoshiConverterFactory.create(moshi))
                       .build();

问题是,当我使用 调用我的网络服务时Retrofit,我得到以下信息Exception

com.squareup.moshi.JsonDataException:java.lang.NumberFormatException:对于输入字符串:“.067000000”在 $[0].timestamp

(请记住,这里的纳秒 .067000000 与我之前给出的 JSON 示例不同,因为它们在不同时间调用 Web 服务)。

我试图在我的 上放置一个断点ZonedDateTimeAdapter,但它从未被调用过。但它影响了 Moshi,因为如果我将它从 中删除Moshi.Builder,错误将变为:

原因:java.lang.IllegalArgumentException:无法序列化抽象类 org.threeten.bp.ZoneId

我还尝试更改ZonedDateTimeAdapter要处理Double而不是String,但它只是将错误消息更改为:

com.squareup.moshi.JsonDataException:java.lang.NumberFormatException:对于输入字符串:“.515376840747E9”在 $[0].timestamp

所以,基本上,我有一堆不断变化的错误消息,不知道我做错了什么。我遵循了 Moshi 文档Custom Adapters,但我不知道还能做什么。

4

1 回答 1

1

您的 JSON 适配器的@ToJson方法接受一个字符串,但时间戳是一个数字。要么将其更改为数字(即双精度),要么传递 JsonReader 而不是 String 并自己读出数字。在这种情况下,您可以调用reader.nextString().

于 2018-01-08T14:17:09.957 回答