自定义异常类jackson序列化jsonMappingException异常

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义异常类jackson序列化jsonMappingException异常相关的知识,希望对你有一定的参考价值。

遇到一个场景,使用slf4j记录异常的时候发现一直抛jsonMappingException

@ExceptionHandler({Exception.class, RuntimeException.class})
@ResponseBody
public ClientResult handleException(Exception ex) {
    if (ex instanceof CustomSystemException) {
        xxxxx
    } else {
        log.error("System Exception", ex);
        return (new ClientResultBuilder()).error(GlobalCodeEnum.ERROR.getCode(), GlobalCodeEnum.ERROR.getMessage()).build();
    }
}

tomcat给我提示是在这一行里面

log.error("System Exception", ex);

乍看之下这个异常打印没啥毛病,问题实际也不是出在这里。

可以看到这个方法返回的是ClientResult类型的类
在返回给前端的时候springmvc会利用jackson序列化成json后返回,真正的坑就在这里了。
可以看到下面的图中,有2个public的get方法,jackson在序列化的时候会通过get方法去获取值,而正好我们这里又是一个code = -1的业务错误返回,导致jackson在序列化的时候调用get方法直接报错了。序列化异常后报了jsonMappingException

解决的方案:

  1. 修改这两个方法代码,不要在序列化的时候抛异常
  2. 修改方法名,不要用get开头

细化分析jackson序列化

jackson序列化的时候默认的字段属性发现规则如下:

所有被public修饰的字段->所有被public修饰的getter->所有被public修饰的setter

若类中的一个private属性,且没有设置publicgettersetter方法,则对该类对象进行序列化时,默认不对这个private属性进行序列化。

若此时任然需要对该private属性进行序列化,可以通过设置自动检测功能来实现:
@JsonAutoDetect(作用在类上)来开启/禁止自动检测

  1. fieldVisibility:字段的可见级别
  2. ANY:任何级别的字段都可以自动识别
  3. NONE:所有字段都不可以自动识别
  4. NON_PRIVATE:非private修饰的字段可以自动识别
  5. PROTECTED_AND_PUBLIC:被protected和public修饰的字段可以被自动识别
  6. PUBLIC_ONLY:只有被public修饰的字段才可以被自动识别
  7. DEFAULT:同PUBLIC_ONLY
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

以上是关于自定义异常类jackson序列化jsonMappingException异常的主要内容,如果未能解决你的问题,请参考以下文章

json之jackson的常用全局配置以及自定义序列化规则

为 Jackson 自定义反序列化程序抛出带有 HTTP 状态代码的自定义异常

使用自定义消息捕获和处理 Jackson 异常

如何在 Jackson 中使用自定义序列化程序?

利用Jackson序列化实现数据脱敏

源码分析springboot自定义jackson序列化,默认null值个性化处理返回值