irpas技术客

【运行报错】使用BeanUtil做beanToMap时,转换字段(可能为null)的属性为String类型_coolcoo1cool

网络投稿 3716

1. 报错信息: 使用Redis代替session做缓存时,需要将redis中未命中的数据,从数据库查出再存入redis缓存首先得将对象转为hashmap(这里使用得是hutool的BeanUtil)且使用StringRedisTemplateredis需要转换成的map的各个字段都是String类型!而bean的各个字段类型各不相同如何在不遍历map(繁琐)的情况下,在转换为map时就直接将字段类型也转换为String?Map<String, Object> map = BeanUtil.beanToMap(shop,new HashMap<>(), CopyOptions.create(). setIgnoreNullValue(true) .setFieldValueEditor((fieldName,fieldValue) -> fieldValue.toString())); stringRedisTemplate.opsForHash().putAll(RedisConstants.CACHE_SHOP_KEY + id,map);

hutool的BeanUtil提供了CopyOptions可以在转换时,做自定义规则 https://apidoc.gitee.com/dromara/hutool/

但是执行报错:java.lang.NullPointerException: null at com.hmdp.service.impl.ShopServiceImpl.lambda$queryById$0(ShopServiceImpl.java:81) ~[classes/:na] at cn.hutool.core.bean.copier.CopyOptions.editFieldValue(CopyOptions.java:258) ~[hutool-all-5.7.17.jar:na] at cn.hutool.core.bean.copier.BeanCopier.lambda$beanToMap$1(BeanCopier.java:233) ~[hutool-all-5.7.17.jar:na] at java.util.LinkedHashMap$LinkedValues.forEach(LinkedHashMap.java:608) ~[na:1.8.0_181] at cn.hutool.core.bean.BeanUtil.descForEach(BeanUtil.java:182) ~[hutool-all-5.7.17.jar:na] at cn.hutool.core.bean.copier.BeanCopier.beanToMap(BeanCopier.java:195) ~[hutool-all-5.7.17.jar:na] at cn.hutool.core.bean.copier.BeanCopier.copy(BeanCopier.java:106) ~[hutool-all-5.7.17.jar:na] at cn.hutool.core.bean.BeanUtil.beanToMap(BeanUtil.java:690) ~[hutool-all-5.7.17.jar:na] 空指针异常! 2. 原因分析: 发现需要转成map得bean中有字段是null而null不能toString()故将代码修改为:Map<String, Object> map = BeanUtil.beanToMap(shop,new HashMap<>(), CopyOptions.create(). setIgnoreNullValue(true) .setFieldValueEditor((fieldName,fieldValue) -> fieldValue + "")); stringRedisTemplate.opsForHash().putAll(RedisConstants.CACHE_SHOP_KEY + id,map); 但还是存在问题:现在空值是以字符串 “null” 存在redis中的当再次点击此商铺,此时缓存命中,故将redis中的hash类型数据转为 shop 对象时,“null” 又无法将string类型的value解析成一个数字类型此时注意到,我代码中明明将 空值忽略掉了setIgnoreNullValue(true) 但debug却发现setIgnoreNullValue(true)并没有 生效 3. 解决方法: 在gitee 上问了作者才知道:https://gitee.com/dromara/hutool/issues/I557F3 setFieldValueEditor优先级要高于ignoreNullValue导致前者首先被触发,因此出现空指针问题。你在setFieldValueEditor中也需要判空这么设计的原因主要是,如果原值确实是null,但是你想给一个默认值,在此前过滤掉就不合理了,而你的值编辑后转换为null,后置的判断就会过滤掉 修改代码:Map<String, Object> map = BeanUtil.beanToMap(shop,new HashMap<>(), CopyOptions.create(). setIgnoreNullValue(true) //.setFieldValueEditor((fieldName,fieldValue) -> fieldValue.toString())); //解决方法:?在setFieldValueEditor中也需要判空 .setFieldValueEditor((fieldName,fieldValue) -> { if (fieldValue == null){ fieldValue = "0"; }else { fieldValue = fieldValue + ""; } return fieldValue; })); stringRedisTemplate.opsForHash().putAll(RedisConstants.CACHE_SHOP_KEY + id,map); return Result.ok(shop); 问题解决!


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #1 #Objectampgt #map