黑马点评-Hutool BeanToMap问题

问题描述

做黑马点评项目的时候,视频中存Redis用的是String。由于String很熟练了 因此想着用Hash结构存,没想到就出错了。

使用Redis做缓存时,如果缓存未命中,需要回写缓存,但是putAll方法要传递Map,不可避免的需要把Bean转成Map。
由于使用StringRedisTemplateredis需要转换成的map的各个字段都是字符串,而bean的各个字段类型各不相同。

Hutool的BeanUtil中封装了很多好用的方法,且提供了允许自定义转换规则的CopyOptions https://apidoc.gitee.com/dromara/hutool/

之前使用过所以就很自然的写成如下:

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);

执行的时候报错

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]

解决思路

dubug过程中发现了我明明设置了setIgnoreNullValue但是貌似没有起作用。
去网上查了一下发现果然有和我一样的人,按照他的思路解决了。
链接如下:
https://huaweicloud.csdn.net/637eef0ddf016f70ae4c9fb1.html

从他的博客发现原来是Hutool的机制
以下内容源自上述链接

  1. 在gitee 上问了作者才知道:gitee Issue
    1. setFieldValueEditor优先级要高于ignoreNullValue导致前者首先被触发,因此出现空指针问题。你在setFieldValueEditor中也需要判空
    2. 这么设计的原因主要是,如果原值确实是null,但是你想给一个默认值,在此前过滤掉就不合理了,而你的值编辑后转换为null,后置的判断就会过滤掉、

最终结果

由于我不希望传递默认值,因此我根据原作者的思路改了一下,问题解决!

Map<String, Object> shopMap = BeanUtil.beanToMap(shop, new HashMap<>(), CopyOptions.create()
                .setIgnoreNullValue(true)
                .setFieldValueEditor((fieldName, fieldValue) ->
                {
                    if (fieldValue == null){

                    }else {
                        fieldValue = fieldValue.toString();
                    }
                    return fieldValue;
                }));

你可能感兴趣的:(JAVA从入门到放弃,疑难杂症,java,redis,开发语言)