使用restTemplate远程调用服务,正常应该接收List<HashMap>数据,但实际却是List<LikedHashMap>经过不断地debug,终于找到了数据被转换成LinkedHashMap的方法,下面我将这个可恶的方法贴出来并解读(解决方式在另一篇https://www.cnblogs.com/gqymy/p/11047327.html)
 
包 com.fasterxml.jackson.databind.deser.std;
 
类: UntypedObjectDeserializer
如果需要绑定“未知”类型的内容,则使用反序列化器实现;声明为基本对象的东西(显式地,或由于类型擦除)。如果是这样,“自然”映射用于将JSON值转换为它们的自然Java对象匹配:JSON数组转换为Java列表(或者,如果配置了object []), JSON对象转换为映射,数字转换为数字,布尔值转换为布尔值,字符串转换为字符串(以及null转换为null)
 
方法: mapObject
方法调用,以将JSON对象映射到Java值
 
//JsonParser 定义用于读取JSON内容的公共API的基类。实例是使用JsonFactory实例的工厂方法创建的
protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOException {
    //访问器,查找当前指向哪个令牌解析器(如果有的话);如果没有,则返回null。如果返回值是非空的,则与令牌关联的数据可以通过其他访问器方法获得
    JsonToken t = p.getCurrentToken();
    String key1;
    if (t == JsonToken.START_OBJECT) {
        //该方法获取下一个令牌(就像调用nextToken()一样)并验证它是否是JsonToken。具有指定名称的FIELD_NAME,并返回该比较的结果。具体方法看下方截图
        key1 = p.nextFieldName();
    } else if (t == JsonToken.FIELD_NAME) {
        //方法来获取与当前令牌关联的名称:for JsonToken。FIELD_NAMEs将与getText()返回的内容相同;对于字段值,它将在字段名之前;对于其他值(数组值、根级值)为null
        key1 = p.getCurrentName();
    } else {
        if (t != JsonToken.END_OBJECT) {
            //2.0API没有此方法,懒得读了
            return ctxt.handleUnexpectedToken(this.handledType(), p);
        }
        key1 = null;
    }
    if (key1 == null) {
        //创建一个容量为2的linkedhashmap
        return new LinkedHashMap(2);
    } else {
        //迭代方法,该方法将充分推进流,以确定下一个令牌的类型,即值类型(包括JSON数组和对象开始/结束标记)。或者换句话说,nextToken()将被调用一次,如果JsonToken。返回                  FIELD_NAME,这是获取字段值的另一个时间。方法对于遍历JSON对象的值条目最有用;当解析器指向值时,通过调用getCurrentName(),字段名仍然可用
            个人觉得类似于迭代器的next()方法
        p.nextToken();
        //反序列化json
        Object value1 = this.deserialize(p, ctxt);
        String key2 = p.nextFieldName();
        if (key2 == null) {
            LinkedHashMap<String, Object> result = new LinkedHashMap(2);
            result.put(key1, value1);
            return result;
        } else {
            p.nextToken();
            Object value2 = this.deserialize(p, ctxt);
            String key = p.nextFieldName();
            LinkedHashMap result;
            if (key == null) {
                result = new LinkedHashMap(4);
                result.put(key1, value1);
                result.put(key2, value2);
                return result;
            } else {
                result = new LinkedHashMap();
                result.put(key1, value1);
                result.put(key2, value2);
                //在这里进行对JsonParser的循环并装进LinkedHashMap中
                do {
                    p.nextToken();
                    result.put(key, this.deserialize(p, ctxt));
                } while((key = p.nextFieldName()) != null);
                return result;
            }
        }
    }
}
 
 
下面是记录的执行方法:
RestTemplate -> postForObject()
RestTemplate -> execute(413)
RestTemplate -> doExecute(444)
HttpMessageConverterExtractor -> extractData(65行)
AbstractJackson2HttpMessageConverter -> read()
AbstractJackson2HttpMessageConverter -> readJavaType()
ObjectMapper -> readValue()
ObjectMapper -> _readMapAndClose(1197行 result = deser.deserialize(p, ctxt);)
CollectionDeserializer -> deserialize(115行)
CollectionDeserializer -> deserialize(134行  执行while循环  else if (typeDeser == null)判断)
UntypedObjectDeserializer -> deserialize(走case 5)
 

RestTemplate Hashmap变为LinkedHashMap源码解读的更多相关文章

  1. LRU算法实现,HashMap与LinkedHashMap源码的部分总结

    关于HashMap与LinkedHashMap源码的一些总结 JDK1.8之后的HashMap底层结构中,在数组(Node<K,V> table)长度大于64的时候且链表(依然是Node) ...

  2. HashTable、HashMap与ConCurrentHashMap源码解读

    HashMap 的数据结构 ​ hashMap 初始的数据结构如下图所示,内部维护一个数组,然后数组上维护一个单链表,有个形象的比喻就是想挂钩一样,数组脚标一样的,一个一个的节点往下挂. ​ 我们可以 ...

  3. LinkedHashMap源码解读

    1. 前言 还是从面试中来,到面试中去.面试官在面试 Redis 的时候经常会问到,Redis 的 LRU 是如何实现的?如果让你实现 LRU 算法,你会怎么实现呢?除了用现有的结构 LinkedHa ...

  4. jdk1.8.0_45源码解读——HashMap的实现

    jdk1.8.0_45源码解读——HashMap的实现 一.HashMap概述 HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射操作.存储的是<key,value>对 ...

  5. java jdk 中HashMap的源码解读

    HashMap是我们在日常写代码时最常用到的一个数据结构,它为我们提供key-value形式的数据存储.同时,它的查询,插入效率都非常高. 在之前的排序算法总结里面里,我大致学习了HashMap的实现 ...

  6. jdk1.8.0_45源码解读——HashSet的实现

    jdk1.8.0_45源码解读——HashSet的实现 一.HashSet概述 HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.主要具有以下的特点: 不保证set的迭代顺 ...

  7. 并发-HashMap和HashTable源码分析

    HashMap和HashTable源码分析 参考: https://blog.csdn.net/luanlouis/article/details/41576373 http://www.cnblog ...

  8. JDK容器类Map源码解读

    java.util.Map接口是JDK1.2开始提供的一个基于键值对的散列表接口,其设计的初衷是为了替换JDK1.0中的java.util.Dictionary抽象类.Dictionary是JDK最初 ...

  9. JDK容器类List,Set,Queue源码解读

    List,Set,Queue都是继承Collection接口的单列集合接口.List常用的实现主要有ArrayList,LinkedList,List中的数据是有序可重复的.Set常用的实现主要是Ha ...

随机推荐

  1. 关于 GraPhlAn 的孤独自学

    最近需要用 GraPhlan 来绘制 taxo分类图,稍微研究了一下 一.简介 官网: http://huttenhower.sph.harvard.edu/GraPhlAn 主要有两个脚本: gra ...

  2. HDU2438:Turn the corner(三分)

    传送门 分析 根据这张图,我们只要使得h<=y即可,可以发现h是一个凸函数,故使用三分,具体见代码 代码 #include<cstdio> #include<cstring&g ...

  3. LuoguP2822 组合数问题(组合数,二维前缀和)

    P2822 组合数问题 输入输出样例 输入样例#1: 复制 1 2 3 3 输出样例#1: 复制 1 输入样例#2: 复制 2 5 4 5 6 7 输出样例#2: 复制 0 7 说明 [样例1说明] ...

  4. 鸟哥私房菜基础篇:Linux 的档案权限与目录配置习题

    猫宁!!! 参考链接:http://linux.vbird.org/linux_basic/0210filepermission.php 鸟哥是为中国信息技术发展做出巨大贡献的人. 1-早期的 Uni ...

  5. ufunc函数

    无灯可看.雨水从教正月半.探茧推盘.探得千秋字字看. 铜驼故老.说著宣和似天宝.五百年前.曾向杭州看上元. ufunc是universal function的缩写,他是一种对数组的每个元素进行运算的函 ...

  6. Poj 3666 Making the Grade (排序+dp)

    题目链接: Poj 3666 Making the Grade 题目描述: 给出一组数,每个数代表当前位置的地面高度,问把路径修成非递增或者非递减,需要花费的最小代价? 解题思路: 对于修好的路径的每 ...

  7. UvaLive6441(期望概率dp)

    1.涉及负数时同时维护最大和最小,互相转移. 2.考场上最大最小混搭转移WA,赛后发现如果是小的搭小的,大的搭大的就可过,类似这种: db a = (C[i] - W[i]) * dp1[i - ][ ...

  8. Codeforces Round #261 (Div. 2) C

    Description Recently Pashmak has been employed in a transportation company. The company has kbuses a ...

  9. Brush (IV) LightOJ - 1018

    题意:平面上有一些点,每刷一次可以把同一条直线上的点都刷光,问最少几次把所有点刷光. 方法: 显然是一个状态压缩dp.ans[S]表示把S集合中点刷掉的最少次数.最开始想到的方法是如果S中只有一个或两 ...

  10. linux下使用svn创建版本库和权限管理

    linux上的svn服务端如何和本地的电脑客户端结合使用 Linux上安装SVN服务器: 第一步:检查是否已安装 # rpm -qa subversion 第二步: 通过yum命令安装svnserve ...