【问题标题】:How to deserialize JSON field with dynamic type?如何反序列化动态类型的 JSON 字段?
【发布时间】:2018-05-24 05:36:13
【问题描述】:

在对 Reddit API 的请求中,每个帖子都有一个名为 edited 的字段关联。这个字段要么有一个boolean 值,要么如果一个帖子已经被编辑,有一个long 值,我认为这是帖子被编辑时的时间戳。我如何在不知道类型的情况下使用 GSON 反序列化它?如果我尝试反序列化为 Boolean 值,如果存在时间戳,则会出现异常。

JSON 响应的下图:

【问题讨论】:

    标签: android json gson retrofit json-deserialization


    【解决方案1】:

    使用 @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);
            }
        }
    
    }
    

    上面的类型适配器是非常自我描述的。当然,它可以以更通用的方式实现,但这超出了这里的范围。另外,请注意它不会选择可以在GsonBuilder 中重新配置的原始Long 类型适配器。使用示例:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 1970-01-01
      相关资源
      最近更新 更多