加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 对于使用Jackson执行Collection的类,反序列化失败

发布时间:2020-12-14 05:26:07 所属栏目:Java 来源:网络整理
导读:我有以下 JSON: { "item": [ { "foo": 1 },{ "foo": 2 } ]} 这基本上是一个包含项目集合的对象. 所以我做了一个反序列化的课: public class ItemList { @JsonProperty("item") ListItem items; // Getters,setters co. // ...} 一切都很好,直到现在为止.
我有以下 JSON:
{
  "item": [
    { "foo": 1 },{ "foo": 2 }
  ]
}

这基本上是一个包含项目集合的对象.

所以我做了一个反序列化的课:

public class ItemList {
  @JsonProperty("item")
  List<Item> items;

  // Getters,setters & co.
  // ...
}

一切都很好,直到现在为止.

现在,为了使我的生活更容易在别的地方,我决定能够迭代ItemList对象并让它实现Collection接口是很好的.

所以基本上我的班成了:

public class ItemList implements Collection<Item>,Iterable<Item> {
  @JsonProperty("item")
  List<Item> items;

  // Getters,setters & co.

  // Generated all method delegates to items. For instance:
  public Item get(int position) {
    return items.get(position);
  }
}

实施工作正常,很好.但是,反序列化现在失败了.

看起来杰克逊变得困惑:

com.fasterxml.jackson.databind.JsonMappingException: Can not
deserialize instance of com.example.ItemList out of START_OBJECT token

我已经尝试添加@JsonDeserialize(as = ItemList.class),但是没有这样做.

有什么办法?

解决方法

显然,它不起作用,因为Jackson使用标准集合解串器作为Java集合类型,它们对ItemList属性一无所知.

它可以使其工作,但不是非常优雅的方式.您需要配置ObjectMapper来替换为相应类型手动创建的bean解串器上的默认集合解串器.我已经写了一个例子,在BeanDeserializerModifier中为使用自定义注释注释的所有类执行此操作.

请注意,我必须重写ObjectMapper以访问ObjectMapper的受保护方法createDeserializationContext,以创建适当的反序列化上下文,因为bean修饰符无法访问它.

这是代码:

public class JacksonCustomList {
    public static final String JSON = "{n" +
            "  "item": [n" +
            "    { "foo": 1 },n" +
            "    { "foo": 2 }n" +
            "  ]n" +
            "} ";

    @Retention(RetentionPolicy.RUNTIME)
    public static @interface PreferBeanDeserializer {

    }

    public static class Item {
        public int foo;

        @Override
        public String toString() {
            return String.valueOf(foo);
        }
    }

    @PreferBeanDeserializer
    public static class ItemList extends ArrayList<Item> {
        @JsonProperty("item")
        public List<Item> items;

        @Override
        public String toString() {
            return items.toString();
        }
    }

    public static class Modifier extends BeanDeserializerModifier {
        private final MyObjectMapper mapper;

        public Modifier(final MyObjectMapper mapper) {
            this.mapper = mapper;
        }

        @Override
        public JsonDeserializer<?> modifyCollectionDeserializer(
                final DeserializationConfig config,final CollectionType type,final BeanDescription beanDesc,final JsonDeserializer<?> deserializer) {
            if (type.getRawClass().getAnnotation(PreferBeanDeserializer.class) != null) {
                DeserializationContext context = mapper.createContext(config);
                try {
                    return context.getFactory().createBeanDeserializer(context,type,beanDesc);
                } catch (JsonMappingException e) {
                   throw new IllegalStateException(e);
                }

            }
            return super.modifyCollectionDeserializer(config,beanDesc,deserializer);
        }
    }

    public static class MyObjectMapper extends ObjectMapper {
        public DeserializationContext createContext(final DeserializationConfig cfg) {
            return super.createDeserializationContext(getDeserializationContext().getParser(),cfg);
        }
    }

    public static void main(String[] args) throws IOException {
        final MyObjectMapper mapper = new MyObjectMapper();
        SimpleModule module = new SimpleModule();
        module.setDeserializerModifier(new Modifier(mapper));

        mapper.registerModule(module);
        System.out.println(mapper.readValue(JSON,ItemList.class));
    }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读