我有以下 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));
    }

}

java – 对于使用Jackson执行Collection的类,反序列化失败的更多相关文章

  1. ios – CGPath和UIBezierPath()有什么区别?

    目前,我正在努力制作一个自定义按钮,我有一个图像,并具有坐标,但我发现您可以通过使用CGPath类或UIBezierPath创建一个按钮/对象类.有人可以告诉我两者有什么区别?解决方法CGPath是CoreGraphics库的不透明类型,而UIBezierPath是UIKit中的Obj-C类.UIBezierPath是一个围绕CGPath的包装,具有更加面向对象的界面和一些方便的方法.使用CGPath可能会略微更快,因为它不必经过Obj-C,并且它具有更高级的功能,如CGPathApply.重要的是,UI

  2. swift 快速奔跑的兔几 本节的内容是:序列化与反序列化

    在cocoa中,我们经常需要向磁盘保存数据块,cocoa将这些数据块表示为NSData对象例如,有一个字符串,将其转换为NSData,可以使用如下方法:我们还可以将对象转化为数据。遵守协议NSCoding的对象可以转换为NSData对象,也可以从NSData对象中加载,方法如下:

  3. Swift中一个类中的枚举enum类型的数据该如何实现序列化NSCoder

    简述昨天在开发中遇到了这样一个问题,需要用NSUserDefaults持久化一些数据,其中需要保存一个自己定义的类对象。结束其实枚举本来就是一个Int,因此我们将其声明为Int型就可以根据Int值初始化了,以此实现序列化和反序列化。

  4. swift json的序列化和反序列化

    还有一点东西没写完,权作笔记参考:http://www.hangge.com/blog/cache/detail_983.html

  5. Swift中对象序列化的实现

    Swift中对象序列化的实现在swift中要使某个类可以序列化,只需要类实现NSCoding协议,并实现协议中的一个必要的构造函数和一个方法,分别对应序列化和反序列化的二个过程。

  6. Alamofire 4.0 迁移指南

    原文:Alamofire4.0MigrationGuide作者:cnoon译者:kemchenj译者注:最近打算把公司项目迁移到Swift3.0,顺手把Alamofire4.0的迁移指南翻译了,之前虽然读过一部分源码,但还是看到了很多新东西,新的Adapter和Retrier我都打算用到项目里,希望大家看完也能够有收获.Alamofire4.0是Alamofire最新的一个大版本更新,一个基于Sw

  7. [HandyJSON] 在Swift语言中处理JSON - 转换JSON和Model

    而HandyJSON是其中使用最舒服的一个库,本文将介绍用HandyJSON来进行Model和JSON间的互相转换。而HandyJSON另辟蹊径,采用Swift反射+内存赋值的方式来构造Model实例,规避了上述两个方案遇到的问题。所以我们要定义一个Mapping函数来做这两个支持:就这样,HandyJSON完美地帮我们进行了JSON到Model类的转换。把Model转换为JSON文本HandyJSON还提供了把Model类序列化为JSON文本的能力,简直无情。

  8. 使用 Swift语言进行 Hadoop 数据流应用程序开发

    如果您发现了问题,或者希望为改进本文提供意见和建议,请在这里指出.在您开始之前,请参阅目前待解决的问题清单.简介本项目包括两类Hadoop流处理应用程序:映射器mapper和总结器reducer。如上所示,在Hadoop上编写流处理程序是一个很简单的工作,也不需要依赖于特定的软件体系。

  9. 数组 – 在swift中存储对数组的引用

    我错过了一些允许我这样做的Swift构造吗?你必须使用NSArray或NSMutableArray,因为SwiftArrays是值类型,所以任何赋值都会复制.

  10. android – 如何在Realm for Java中将RealmObject序列化为JSON?

    也就是说,使用RealmObject并将其序列化为JSON?它还应该序列化该对象内的任何RealmList.解决方法来自英国的基督徒在这里.RealmforAndroid目前没有任何此类方法,虽然核心数据库实际上支持JSON序列化,所以现在你要么必须手动操作,要么使用像GSON这样的第三方工具然而).

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部