2022年8月更文挑战4-缺失无参构造函数导致jackson反序列化失败及解决办法

855 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

缺失无参构造函数导致jackson反序列化失败及解决办法

前文

前面曾提到feign在调用时,当返回结果类不包含无参构造函数,会导致反序列化失败。实际上feign底层是采用jackson进行反序列化操作。本文将从jackson的角度探索这一问题及解决方案。

jackson反序列化

首先采用jackson进行反序列化操作,目标类为info,且目标类中不包含无参构造函数。具体代码如下:

public static void main(String[] args) {
    String str = "{"a":"aa","b":"bb"}";
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        Info info = objectMapper.readValue(str,Info.class);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

如代码中所示,我们将序列化后的结果利用jackson进行反序列化,而反序列化的info类中不包含无参的构造函数。而执行后出现如下提示:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `cc.crrc.Test$Info` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor
 at [Source: (String)"{"a":"aa","b":"bb"}"; line: 1, column: 2]

很明显,提示信息与之前feign中的提示信息类似,都是说明需要无参的构造函数进行反序列化,也证实了feign底层采用jackson进行反序列化操作。

利用jackson如何进行无参反序列化

那么如何进行无参函数的反序列化呢。对代码进行一下改造。

public static void main(String[] args) {
        String str = "{"a":"aa","b":"bb"}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            JsonNode jsonNode = objectMapper.readTree(str);
            Info info = new Info(jsonNode.get("a").asText(),jsonNode.get("b").asText());
//            Info info = objectMapper.readValue(str,Info.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

如上述代码所示,我们将利用jackson直接进行反序列化修改为利用jackson进行数据的读取,读取后利用有参的构造函数,直接进行对象的初始化即可。这样虽然没有实现无参构造函数的自动反序列化,但是也通过另一种方式完成了对象的生成。不过对于feign来说,并不能通过该方案进行处理。一种理论上可行的方案应该是对于反序列化器的定制。

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。