SLF4J: Failed toString() invocation on an object of type [java.util.HashMap] 的解决

SLF4J: Failed toString() invocation on an object of type [java.util.HashMap] 的解决

  1. 问题背景:

对体类Bean进行 BeanUtils.describe(purchaseCatalogBo);转换成Map,但是日志打印报错,并且从map里获取参数报错,报错明细如下:

SLF4J: Failed toString() invocation on an object of type [java.util.HashMap]
Reported exception:
java.lang.StackOverflowError
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.util.AbstractMap.toString(AbstractMap.java:534)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.util.AbstractMap.toString(AbstractMap.java:536)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.util.AbstractCollection.toString(AbstractCollection.java:462)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.util.AbstractMap.toString(AbstractMap.java:536)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.util.AbstractMap.toString(AbstractMap.java:536)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.util.AbstractCollection.toString(AbstractCollection.java:462)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.util.AbstractMap.toString(AbstractMap.java:536)
        at java.lang.String.valueOf(String.java:2994)
        at java.lang.StringBuilder.append(StringBuilder.java:131)

并且更奇怪的是在本机验证是没有问题的,只有在线上环境才会出现,很是令人头疼,心想肯定是哪里的底层没有涉及到导致这个表面的错误浮现。

  1. 解决方案:
    使用阿里巴巴的json转换。
 将 Map reqMap = BeanUtils.describe(allChannelsCheckResReq);  改成
 Map reqMap = JSON.parseObject(JSON.toJSONString(allChannelsCheckResReq), Map.class);
  1. 问题原因

经过网上查证,问题原因很可能是 实体类使用JPA方法来实现实体类之间的对应关系和BeanUtils.describe()方法的tostring方法都无休止地相互调用引起的。因为BeanUtils.describe()的原理是 BeanUtils调用 BeanUtilsBean的这个getNestedProperty方法,该方法在读取值之后,会再调用一次(getConvertUtils().convert(value));,进行类型转化成String。即转化出来的Map的value都是String。

  1. 总结:
    BeanUtils虽然做了封装提高了开发效率,但是阿里巴巴的json感觉更优秀点。以后转换多多使用json
  2. 拓展:

BeanUtils.describe与PropertyUtils.describe区别
BeanUtils.describe转换出来的值为string; PropertyUtils.describe 转换出来的值不做转换,但是两者都会将class也转换到Map里,如图所示

PurchaseCatalogBo purchaseCatalogBo=new PurchaseCatalogBo();
        purchaseCatalogBo.setRsId("123");
        purchaseCatalogBo.setPricePre(88);
        purchaseCatalogBo.setUpdatime(new Date());
        Map<String, String> describe = BeanUtils.describe(purchaseCatalogBo);
        System.out.println(JSON.toJSONString(describe));
        Map<String, Object> describe1 = PropertyUtils.describe(purchaseCatalogBo);
        System.out.println(JSON.toJSONString(describe1));
        Map map = JSON.parseObject(JSON.toJSONString(purchaseCatalogBo), Map.class);
        System.out.println(JSON.toJSONString(map));

输出结果:
BeanUtils.describe{“pricePre”:“88”,“rsId”:“123”,“updatime”:“Mon Feb 03 20:19:18 CST 2020”,“class”:“class com.chinaunicom.cbss2.rc.external.bean.PurchaseCatalogBo”}

PropertyUtils.describe{“pricePre”:88,“rsId”:“123”,“updatime”:1580732358529,“class”:“com.chinaunicom.cbss2.rc.external.bean.PurchaseCatalogBo”}

Json
{“updatime”:1580732358529,“pricePre”:88,“rsId”:“123”}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值