• 【工作技术栈】【源码阅读】解决restTemplate提取LocalDateTime等特殊类时序列化报错问题


    前言

    最近代码重构时将方法调用解耦成restful接口调用,期间会遇到很多序列化和反序列化不符合需求的问题,这次遇到的是resttemlate请求完成之后提取responese时对body进行特定类的反序列化时报错问题的一个记录。

    现象

    版本(抛开版本就是耍流氓~)

            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>fastjsonartifactId>
                <version>1.2.83version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    反序列化的model类中存在一个成员变量类型LocalDateTime,序列化时报了一个错误,如下图:
    在这里插入图片描述

    分析原因

    这个问题我百度了很多地方,然后写了demo,发现似乎不管是fastjson还是jackson都是能序列化,但是反序列化的时候会报错。。。
    解决办法也是非常多,比如针对特定的类配置全局的转换器,特殊处理等等。但是我们的项目已经给springboot配置了全局的json转换器为fastjson了,但是报错似乎是jackson报的错,当时我就很懵逼,但是仍然想快速解决这个问题,于是搜resttemplate为什么反序列化报错,然后结果也有:
    1、刚开始直接选择将全局的转换器配置一个单独的localdatetime处理,然而并没有什么卵用,很显然方向都错误了。。。
    2、替换template转换器为fastjson,这个方式我已经怀疑resttemplate自己的转换器可能是独立的,不受全局的控制,然而转换完之后所有的请求全部报fastjson转换格式错误。因为springboot的controller返回值序列化还是jackson格式的擦。。
    3、替换template中的某个convert的objectmapper,这个方法其实已经很ok了,但是方法是直接new一个新的objectmapper,虽然没有出什么错误,但是并没有生效。。。
    到这里我是真的没有什么办法了,唉,只能到我们“最喜欢的“看源码时间。。
    这里的源码应该从resttemplate发同步请求之后提取response的地方看,也就是异常的地方:
    在这里插入图片描述
    首先追到提取data的地方
    在这里插入图片描述

    进去之后发现这里会挑出来一个交GenericHttpMessageConverter,这个接口的解释是专门为了提取特定类的一个序列化转化器所设计的,打断点后就会进入到第二个红框,这里发现convert里面有个对象就是objectmapper,也就是我百度到的第三个方法,,方法里面有一个timemodule的配置,所以这里我选择继续看第三个方法为什么没有生效?
    在这里插入图片描述
    上图就是第三个方法,虽然没有生效,但是基本已经快要成功了,为什么没有生效呢?断点到我要注册timemodule的地方发现我还没有注册呢,这个时候就已经有javatimemodule了。。。哪来的?我帮大家看了一下函数栈,在spring初始化的时候会有一个默认的javatimemodule注册进去,,,行吧,那我后面又再次注册了啊,为什么没有用呢?
    在这里插入图片描述
    看到803行的时候,唉,,,早点看源码就好了,这里有个预防重复模块注册的标志位啊。。。这谁受得了啊哥们儿。。。
    行吧到这里基本就结束了,只要吧这个开关关掉注册完自己的再打开就行了。。。详细看下解决方法吧,这个其实基本解决了所有类的自定义特殊处理了。希望对大家有帮助。

    解决方法

    首先定义自己特定类的两个序列化类型,可以是内部静态类

    这里没办法给大家复制粘贴哈,因为数据安全的原因,我又懒得手打一遍了。。。

    在这里插入图片描述
    在这里插入图片描述
    下面是配置全局的resttemplate的代码,当初始化完成resttemplateBean的时候先别慌返回,这里进行一下自己module的替换,记得把开关关掉就行。网上给的办法是直接new一个objectmapper,但是这里我觉得改的范围越少越好,不如只替换objectmapper的零件吧。
    在这里插入图片描述

    思考感悟

    早看源码早享受,晚看源码晚交付。

  • 相关阅读:
    1 - SpringMVC
    (完全解决)pycharm运行或者调试项目的时候报错:test setup failed
    对话框管理器第一章:先热热身
    构建自动化测试环境:使用Docker和Selenium!
    [Android显示学习]RenderThread渲染
    机房管理技能,医疗行业必备!
    Java单例模式——线程安全的懒汉模式
    说说CDN和负载均衡具体是怎么实现的
    C语言期末复习题(下)
    Java教程:RocketMq集群消息核心知识与SpringBoot整合并实现生产者与消费者
  • 原文地址:https://blog.csdn.net/qq_39760347/article/details/127713784