TL; DR:

我的问题是:

1-如何为Adapter"timestamp": 1515375392.225制作ZonedDateTime

2-根据documentation的说明,如果我需要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
  },
.......
}]


timestampJackson JavaTimeModule进行的自动转换,它以十进制数的形式将ZonedDateTime转换为timestamp String,该十进制数表示secondsnanosecondsInstant

为了解析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调用Web服务时,得到以下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:
  对于输入字符串:$。[0] .timestamp上的“ .515376840747E9”


因此,基本上,我有一堆不断变化的错误消息,不知道我在做什么错。我遵循了Custom Adapters上的Moshi文档,但我不知道该怎么办。

最佳答案

JSON适配器的@ToJson方法接受字符串,但时间戳是数字。可以将其更改为数字(即双精度),也可以通过JsonReader而不是String来自己读取数字。在这种情况下,您可以呼叫reader.nextString()

关于android - 未调用Moshi自定义适配器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48143405/

10-10 08:35