我的问题是:
1 - 如何为Adapter
"timestamp": 1515375392.225
制作ZonedDateTime
。
2 - 如果我需要moshi对象来获取此适配器,如何根据{{3}在List<Report>
对象moshi
中注册Builder
适配器}吗
我的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
documentation自动转换,它以十进制数字的形式将ZonedDateTime
转换为timestamp String
来自seconds
的{{1}}和nanoseconds
。
为了解析JSON Instant
,我制作了以下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
:
com.squareup.moshi.JsonDataException:java.lang.NumberFormatException: 对于输入字符串:&#34; .067000000&#34;在$ [0] .timestamp
(请记住,这里的纳秒数.067000000与我之前提供的JSON示例相同,因为他们在不同的时间调用了web服务。)
我试图在Exception
上放置一个断点,但它从未被调用过。但是它影响了Moshi,因为如果我从ZonedDateTimeAdapter
删除它,则错误会变为:
引起:java.lang.IllegalArgumentException:无法序列化 抽象类org.threeten.bp.ZoneId
我还尝试更改Moshi.Builder
以处理ZonedDateTimeAdapter
而不是Double
,但它只是将错误消息更改为:
com.squareup.moshi.JsonDataException:java.lang.NumberFormatException: 对于输入字符串:&#34; .515376840747E9&#34;在$ [0] .timestamp
所以,基本上,我有一堆不断变化的错误信息,不知道我做错了什么。我跟踪了String
上的Moshi文档,我不知道还能做些什么。
答案 0 :(得分:1)
您的JSON适配器的@ToJson
方法正在接受字符串,但时间戳是一个数字。要么将其更改为数字(即双精度型),要么传递JsonReader而不是String,并自行读取数字。在这种情况下,可以调用reader.nextString()
。