Можете ли вы напрямую отобразить временные метки ISO 8601 в OffsetDateTime или ZonedDateTime с помощью Retrofit 2 и Gson?
На Android, используя Retrofit 2 и его конвертер Gson, вы можете отобразить строки ISO 8601 как "2016-10-26T11:36:29.742+03:00"
(в ответе JSON бэкэнда) непосредственно в java.util.Date
поля в POJO. Это работает аккуратно из коробки.
Теперь я использую библиотеку ThreeTenABP (в ней представлены версии классов java.time с обратным портированием), и мне было интересно, можно ли напрямую отобразить строки меток времени ISO в более красивый, более современный тип, такой как OffsetDateTime
или же ZonedDateTime
,
В большинстве случаев (например, Java 8 на стороне сервера), очевидно, преобразование из2016-10-26T11:36:29.742+03:00
В OffsetDateTime
или же ZonedDateTime
было бы просто, так как строка даты включает информацию о часовом поясе.
Я пытался использовать оба OffsetDateTime
а также ZonedDateTime
(вместо даты) в моих POJO, но по крайней мере из коробки это не работает. Есть идеи, если вы можете сделать это на Android с Retrofit 2?
зависимости:
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'
Сборка экземпляра Retrofit:
new Retrofit.Builder()
// ...
.addConverterFactory(GsonConverterFactory.create())
.build();
2 ответа
Вы можете:
Создайте адаптер типа, который реализует
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, которые вы хотите, оставлена в качестве упражнения.
Зарегистрируйте адаптер типа на
GsonBuilder
при строительствеGson
пример:GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(LocalDate.class, new YourTypeAdapter()); Gson gson = gsonBuilder.create();
Зарегистрировать
Gson
экземпляр сRetrofit.Builder
:builder.addConverterFactory(GsonConverterFactory.create(gson));
Используйте типы ThreeTen в ваших классах моделей Gson с Retrofit.
Точно так же, если вы хотите сериализовать типы ThreeTen в JSON, также реализуйте JsonSerializer
в вашем типе адаптера.
Я создал небольшую библиотеку, которая делает именно то, что предлагает laalto в своем ответе, не стесняйтесь ее использовать: Android Java Time Gson Deserializer