您可以使用 Retrofit 2 和 Gson 将 ISO 8601 时间戳直接映射到 OffsetDateTime 或 ZonedDateTime 吗?
Can you directly map ISO 8601 timestamps into OffsetDateTime or ZonedDateTime with Retrofit 2 and Gson?
在 Android 上,使用 Retrofit 2 及其 Gson 转换器,您可以映射
ISO 8601 字符串,如 "2016-10-26T11:36:29.742+03:00"
(在后端的 JSON 响应中)直接进入 POJO 中的 java.util.Date
字段。这开箱即用。
现在,我正在使用 ThreeTenABP 库(它提供 java.time 类 的向后移植版本),我想知道是否可以映射 ISO将时间戳字符串直接转换为更好、更现代的类型,例如 OffsetDateTime
或 ZonedDateTime
.
在大多数情况下(想想服务器端的Java 8),显然,从“2016-10-26T11:36:29.742+03:00
”到OffsetDateTime
的转换或者ZonedDateTime
会很简单,因为日期字符串包含时区信息。
我尝试在我的 POJO 中同时使用 OffsetDateTime
和 ZonedDateTime
(而不是日期),但至少开箱即用它不起作用。如果您可以使用 Retrofit 2 在 Android 上干净地做到这一点,您有什么想法吗?
依赖关系:
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();
您可以:
创建一个类型适配器来实现 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 类型实现类似留作练习。
在构建 Gson
实例时在 GsonBuilder
上注册类型适配器:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(LocalDate.class, new YourTypeAdapter());
Gson gson = gsonBuilder.create();
用Retrofit.Builder
注册Gson
实例:
builder.addConverterFactory(GsonConverterFactory.create(gson));
在你的 Gson 模型中使用 ThreeTen 类型 类 和 Retrofit。
类似地,如果您想将 ThreeTen 类型序列化为 JSON,也请在您的类型适配器中实现 JsonSerializer
。
我创建了一个小型库,完全按照 laalto 在他的回答中提出的建议进行操作,请随意使用它:Android Java Time Gson Deserializers
在 Android 上,使用 Retrofit 2 及其 Gson 转换器,您可以映射
ISO 8601 字符串,如 "2016-10-26T11:36:29.742+03:00"
(在后端的 JSON 响应中)直接进入 POJO 中的 java.util.Date
字段。这开箱即用。
现在,我正在使用 ThreeTenABP 库(它提供 java.time 类 的向后移植版本),我想知道是否可以映射 ISO将时间戳字符串直接转换为更好、更现代的类型,例如 OffsetDateTime
或 ZonedDateTime
.
在大多数情况下(想想服务器端的Java 8),显然,从“2016-10-26T11:36:29.742+03:00
”到OffsetDateTime
的转换或者ZonedDateTime
会很简单,因为日期字符串包含时区信息。
我尝试在我的 POJO 中同时使用 OffsetDateTime
和 ZonedDateTime
(而不是日期),但至少开箱即用它不起作用。如果您可以使用 Retrofit 2 在 Android 上干净地做到这一点,您有什么想法吗?
依赖关系:
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();
您可以:
创建一个类型适配器来实现
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 类型实现类似留作练习。
在构建
Gson
实例时在GsonBuilder
上注册类型适配器:GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(LocalDate.class, new YourTypeAdapter()); Gson gson = gsonBuilder.create();
用
Retrofit.Builder
注册Gson
实例:builder.addConverterFactory(GsonConverterFactory.create(gson));
在你的 Gson 模型中使用 ThreeTen 类型 类 和 Retrofit。
类似地,如果您想将 ThreeTen 类型序列化为 JSON,也请在您的类型适配器中实现 JsonSerializer
。
我创建了一个小型库,完全按照 laalto 在他的回答中提出的建议进行操作,请随意使用它:Android Java Time Gson Deserializers