Moshi Custom Adapter не вызывается

TL;DR:

Мои вопросы:

1 - Как я могу сделать Adapter для "timestamp": 1515375392.225 в ZonedDateTime ,

2 - Как я могу зарегистрировать List<Report> адаптер в moshi объект Builder если мне нужен объект moshi, чтобы получить этот адаптер, в соответствии с документацией?


Моя строка 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 это автоматическое преобразование, сделанное JacksonJavaTimeModule, он преобразует ZonedDateTime к timestamp String в форме десятичного числа, представляющего seconds а также nanoseconds из Instant,

Для того, чтобы разобрать 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, который я приводил ранее, поскольку они вызывали веб-сервис в разное время).

Я пытался установить точку останова на моем ZonedDateTimeAdapter, но это никогда не называется. Но это влияет на Моши, потому что если я удалю его из Moshi.Builder ошибка изменится на:

Вызвано: java.lang.IllegalArgumentException: Невозможно сериализовать абстрактный класс org.threeten.bp.ZoneId

Я также пытался изменить ZonedDateTimeAdapter иметь дело с Double вместо String, но это просто изменяет сообщение об ошибке на:

com.squareup.moshi.JsonDataException: java.lang.NumberFormatException: для входной строки: ".515376840747E9" в $[0].timestamp

Так что, по сути, у меня есть куча меняющихся сообщений об ошибках, и я не знаю, что я делаю не так. Я следовал документации Моши на Custom Adapters и я не знаю, что еще делать.

1 ответ

Ваш JSON-адаптер @ToJson методы принимает строку, но отметка времени является числом. Либо измените его на число (т.е. двойное), либо передайте JsonReader вместо String и прочитайте число самостоятельно. В этом случае вы можете позвонить reader.nextString(),

Другие вопросы по тегам