Json反序列化之ObjectMapper(自定义实现反序列化方法)

本文介绍了如何使用ObjectMapper进行Json反序列化,并针对第三方接口返回数据类型不一致的问题,提出了两种解决方案:1. 在bean的set方法内进行判断处理;2. 继承JsonDeserializer,自定义反序列化方法。详细解析了Json反序列化过程,包括JsonParser、JavaType的获取,以及BeanDeserializer的工作原理。
摘要由CSDN通过智能技术生成

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/50868105



     对于服务器端开发人员而言,调用第三方接口获取数据,将其“代理”转化并返给客户端几乎是家常便饭的事儿。    一般情况下,第三方接口返回的数据类型是json格式,而服务器开发人员则需将json格式的数据转换成对象,继而对其进行处理并封装,以返回给客户端。

     在不是特别考虑效率的情况下(对于搜索、缓存等情形可以考虑使用thrift和protobuffer),通常我们会选取jackson包中的ObjectMapper类对json串反序列化以得到相应对象。通常会选取readValue(String content, Class<T>valueType)方法进行反序列化。

     ObjectMapper的readValue方法将json串反序列化为对象的过程大致为: 依据传入的json串和目标对象类型分别创建JsonParse和JavaType,随后生成DeserializationConfig、DeserializationContext、JsonDeserializer,其中JsonDeserializer的实现类决定将要执行哪一种类型解析(Bean、Map、String等),JsonParse中存储了待解析字符串及其它信息,在解析的过程中通过token来判断当前匹配的类型(例如:如果遇到{,将其判断为对象类型的起始位置;遇到[,将其判断为集合类型的起始位置),一旦确定了类型,则跳入与之对应的反序列化类中进行处理,得到结果,然后token往后移动,接着解析下一个串。可以看做类似递归的方式进行解析,当通过token判断为一个对象时,则会跳入BeanDeserializer中进行解析,随后遍历该对象的所有字段,如果字段是字符串,则跳到StringDeserializer中进行解析,如果字段是数组,则跳到CollectionDeserializer中进行解析,直到解析完整个字符串为止。也可以看做类似而树的深度遍历,理解起来还是挺容易的。


下面将简单介绍ObjectMapper的readValue方法进行反序列化的过程:
a:通过json串和对象类型得到JsonParser和JavaType。

    public <T> T readValue(String content, Class<T> valueType)
        throws IOException, JsonParseException, JsonMappingException
    {
        return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType));
    } 

    //获取json解析器,其中包含带解析的串
    public JsonParser createParser(String content) throws IOException, JsonParseException {
        final int strLen = content.length();
        // Actually, let's use this for medium-sized content, up to 64kB chunk (32kb char)
        if (_inputDecorator != null || strLen > 0x8000 || !canUseCharArrays()) {
            // easier to just wrap in a Reader than extend InputDecorator; or, if content
            // is too long for us to copy it over
            return createParser(new StringReader(content));
        }
        IOContext ctxt = _createContext(content, true);
        char[] buf = ctxt.allocTokenBuffer(strLen);
        content.getChars(0, strLen, buf, 0);
        return _createParser(buf, 0, strLen, ctxt, true);
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值