使用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. ccflow_004请假流程-傻瓜表单-经典模式

    ccflow_004请假流程-傻瓜表单-经典模式

  2. e_pro list 1

    uncle  n. 叔叔; 伯父; 舅父; 姑父,姨父; farm n. 农家; 农田; 农场,农庄; 畜牧场; corner n. 拐角; 角落,角; 困境; [商] 囤积;     vi. 驾车转 ...

  3. CodeForces 622C

    题意: 给你一个数组,m个询问,l,r,x;让你输出在区间[ l , r ]上哪个位置不等于x. 思路: 额..我这个思路还是剽来的...不过真心赞啊. 开个p数组,直接记录数组每个元素的位置,并且实 ...

  4. 洛谷P3577 [POI2014]TUR-Tourism

    给定一个n个点,m条边的无向图,其中你在第i个点建立旅游站点的费用为Ci.在这张图中,任意两点间不存在节点数超过10的简单路径.请找到一种费用最小的建立旅游站点的方案,使得每个点要么建立了旅游站点,要 ...

  5. 洛谷P3825 [NOI2017]游戏(2-SAT)

    传送门 果然图论的题永远建图最麻烦……看着题解代码的建图过程真的很珂怕…… 先不考虑地图$x$,那么每一个地图都只能用两种赛车,于是我们可以用2-SAT来搞,用$i$表示这个地图能用的第一辆车,$i' ...

  6. Milking Grid POJ - 2185 || 最小覆盖子串

    Milking Grid POJ - 2185 最小覆盖子串: 最小覆盖子串(串尾多一小段时,用前缀覆盖)长度为n-next[n](n-pre[n]),n为串长. 当n%(n-next[n])==0时 ...

  7. URAL 7077 Little Zu Chongzhi's Triangles(14广州I)

    题目传送门 题意:有n根木棍,三根可能能够构成三角形,选出最多的三角形,问最大面积 分析:看到这个数据范围应该想到状压DP,这次我想到了.0010101的状态中,1表示第i根木棍选择,0表示没选,每一 ...

  8. 递推DP URAL 1031 Railway Tickets

    题目传送门 /* 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 注意:s1与s2大小不一定,坑! 详细解释:http://blog.csdn.net/kk303/article/d ...

  9. C8051特点

    C8051与传统51的区别在于优先权交叉开关.系统时钟.SFR寄存器几个方面: 一 优先权交叉开关:传统的51外设功能是固定分配或者复用分配到指定引脚,而C8051则是通过优先权交叉开关设置,即要想分 ...

  10. 10.JAVA-接口、工厂模式、代理模式、详解

    1.接口定义 接口属于一个特殊的类,这个类里面只能有抽象方法和全局常量  (该概念在JDK1.8之后被打破,在1.8后接口中还可以定义普通方法和静态方法,在后续章节会详讲) 1.1 接口具有以下几个原 ...