具有多种格式的Moshi LocalDateTime适配器 [英] Moshi LocalDateTime adapter with multiple format
问题描述
默认情况下,ThreeTenABP.LocalDateTime转换为
By default, ThreeTenABP.LocalDateTime is converted to
{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}
我可以编写一个适配器以支持ISO日期字符串2018-04-10T03:45:26.009
I can write an adapter to support ISO date string 2018-04-10T03:45:26.009
class LocalDateTimeAdapter {
@ToJson
fun toJson(value: LocalDateTime): String {
return FORMATTER.format(value)
}
@FromJson
fun fromJson(value: String): LocalDateTime {
return FORMATTER.parse(value, LocalDateTime.FROM)
}
companion object {
private val FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME
}
}
如何编写支持两种格式的适配器(fromJson)
How can I write an adapter which can support both format (fromJson)
-
{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}
-
2018-04-10T03:45:26.009
{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":18}}
2018-04-10T03:45:26.009
除了确定在fromJson
中使用哪种格式外,我很好奇Moshi在LocalDateTime内部如何执行toJson/fromJson
Beside identifying which the format is used in fromJson
, I am curious how Moshi internally perform toJson/fromJson for LocalDateTime
推荐答案
您需要使用JsonReader.peek()
确定传入JSON的格式,然后采取相应措施.
You’ll need to use JsonReader.peek()
to determine the format of the incoming JSON, and then take action accordingly.
首先安装将LocalDateTime
转换为字符串的适配器.该适配器应使用限定符注释.
First install an adapter that converts LocalDateTime
to a string. That adapter should use a qualifier annotation.
@Retention(RetentionPolicy.RUNTIME)
@JsonQualifier
@interface DateString {
}
接下来创建字符串适配器.它应该简单明了,并且可以委托给Moshi内置的Rfc3339DateJsonAdapter.
Next create the string adapter. It should be straightforward, and might delegate to Moshi’s built-in Rfc3339DateJsonAdapter.
public final class LocalDateAsStringAdapter {
@ToJson String toJson(@DateString LocalDateTime localDateTime) {
...
}
@FromJson @DateString LocalDateTime fromJson(String string) {
...
}
}
最后创建一个适配器,该适配器可以委派给Moshi的内置适配器(该适配器将使用{...}
)或您的字符串适配器.该用户更喜欢字符串格式,但是您可以做自己喜欢的事情.
Finally create an adapter that delegates either to Moshi’s built in adapter (that one will use {...}
) or to your string adapter. This one prefers the string format, but you can do what you like.
public final class MultipleFormatsDateAdapter {
@ToJson void toJson(JsonWriter writer, LocalDateTime value,
@DateString JsonAdapter<LocalDateTime> stringAdapter) throws IOException {
stringAdapter.toJson(writer, value);
}
@FromJson LocalDateTime fromJson(JsonReader reader, @DateString JsonAdapter<LocalDateTime> stringAdapter,
JsonAdapter<LocalDateTime> defaultAdapter) throws IOException {
if (reader.peek() == JsonReader.Token.STRING) {
return stringAdapter.fromJson(reader);
} else {
return defaultAdapter.fromJson(reader);
}
}
}
之所以可行,是因为Moshi允许您为@ToJson
和@FromJson
方法声明多个JsonAdapter
参数,并且这些参数可能带有注释.
This works because Moshi lets you declare multiple JsonAdapter
arguments to the @ToJson
and @FromJson
methods, and these arguments may be annotated.
如果类型相同,它也依赖于此功能的工作方式.在这里,我们通过委派另一个JsonAdapter<LocalDateTime>
来创建JsonAdapter<LocalDateTime>
.当类型相同时,Moshi将使用其nextAdapter()
功能进行合成.
It also relies on the way this feature works if the types are the same. Here we’re making a JsonAdapter<LocalDateTime>
by delegating to another JsonAdapter<LocalDateTime>
. When the types are the same Moshi uses its nextAdapter()
feature for composition.
这篇关于具有多种格式的Moshi LocalDateTime适配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!