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
это автоматическое преобразование, сделанное Jackson
JavaTimeModule
, он преобразует 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()
,