在对Reddit API的请求中,每个帖子都有一个名为edited
的字段。此字段具有boolean
值,或者如果已编辑帖子,则具有long
值,我认为该值是编辑帖子的时间戳。如何在没有知道类型的情况下使用GSON 对其进行反序列化?如果我尝试反序列化为Boolean
值,如果存在时间戳,我会收到异常。
下面的JSON响应图片:
答案 0 :(得分:2)
使用@JsonAdapter
注释动态字段可能是解决此问题的最简单方法(假设您有DTO类):
final class Datum {
@JsonAdapter(MaybeLongTypeAdapter.class)
final Long edited = null;
}
MaybeLongTypeAdapter
如下:
final class MaybeLongTypeAdapter
extends TypeAdapter<Long> {
private MaybeLongTypeAdapter() {
}
@Override
public void write(final JsonWriter out, final Long value) {
throw new UnsupportedOperationException();
}
@Override
public Long read(final JsonReader in)
throws IOException {
switch ( in.peek() ) {
case NULL:
return null;
case BOOLEAN:
if ( in.nextBoolean() ) {
throw new JsonSyntaxException("Unexpected `true` at " + in);
}
return null;
case NUMBER:
return in.nextLong();
default:
throw new JsonSyntaxException("Unexpected element at " + in);
}
}
}
上面的类型适配器非常具有自描述性。当然,它可以以更通用的方式实现,但它超出了范围。另请注意,它不会选择可在Long
中重新配置的原始GsonBuilder
类型适配器。使用示例:
private static final Gson gson = new Gson();
private static final Type listOfDatumType = new TypeToken<List<Datum>>() {}.getType();
public static void main(final String... args) {
final String json = "[{\"edited\": false},{\"edited\": 1527130582}]";
final List<Datum> data = gson.fromJson(json, listOfDatumType);
for ( final Datum datum : data ) {
System.out.println(datum.edited);
}
}
输出:
空
1527130582