麻了,不要再动不动就BeanUtil.copyProperties!!!-全球新动态
2023-04-16 09:25:15 博客园
前言

最近项目上要求升级一个工具包hutool的版本,以解决安全漏洞问题,这不升级还好,一升级反而捅出了更大的篓子,究竟是怎么回事呢?


(资料图片仅供参考)

事件回顾

我们项目原先使用的hutool版本是5.7.2,在代码中,我们的数据传输对象DTO和数据实体对象中大量使用了工具包中的BeanUtil.copyProperties(), 大体代码如下:

数据传输对象
@Data@ToStringpublic class DiagramDTO {    // 前端生产的字符串id    private String id;    private String code;    private String name;}
数据实体对象
@Data@ToStringpublic class Diagram {    private Integer id;    private String code;    private String name;}
业务逻辑
public class BeanCopyTest {    public static void main(String[] args) {        // 前端传输的对象        DiagramDTO diagramDTO = new DiagramDTO();        // 如果前端传入的id事包含e的,升级后就会报错        diagramDTO.setId("3em3dgqsgmn0");        diagramDTO.setCode("d1");        diagramDTO.setName("图表");        Diagram diagram = new Diagram();        // 关键点,数据拷贝        BeanUtil.copyProperties(diagramDTO, diagram);        System.out.println("数据实体对象:" + diagram);        //设置id为空,自增        diagram.setId(null);        //保存到数据库中 TODO        //diagramMapper.save(diagram);    }}

升级前,hutool是5.7.2版本下,执行结果如下图。

BeanUtil.copyProperties虽然字段类型不一样,但是做了兼容处理,所以业务没有影响业务逻辑。

升级后,hutool是5.8.8版本,执行结果如下图所示:

执行报错,因为升级后的版本修改了实现,增加了下面的逻辑,如果包含E, 就会抛错,从而影响了业务逻辑,同时这个id是否包含e又是随机因素,到了生产才发现,就悲剧了。分析探讨

我发现大部分人写代码都喜欢偷懒,在上面的场景中,虽然BeanUtil.copyProperties用的一时爽,但有时候带来的后果是很严重的,所以很不推荐这种方式。为什么这么说呢?

比如团队中的某些人偷偷改了数据传输对象DTO,比如修改了类型、删去了某个字段。用BeanUtil.copyProperties的方式压根无法在编译阶段发现,更别提修改的影响范围了,这就只能把风险暴露到生产上去了。那有什么更好的方法呢?

推荐方案原始的getset方式

我是比较推崇这种做法的,比如现在DiagramDTO删去某个字段,编译器就会报错,就会引起你的注意了,让问题提前暴露,无处遁形。

你可能觉得站着说话不腰疼,字段少好,如果字段很多还不得写死啊,我这里推荐一个IDEA的插件,可以帮你智能生成这样的代码。

话不多说,自己玩儿去~~

使用开源库ModelMapper

ModelMapper是一个开源库,可以很方便、简单地将对象从一种类型映射到另一种类型,底层是通过反射来自动确定对象之间的映射,还可以自定义映射规则。

private static void testModelMapper() {        ModelMapper modelMapper = new ModelMapper();        DiagramDTO diagramDTO = new DiagramDTO();        diagramDTO.setId("3em3dgqsgmn0");        diagramDTO.setCode("d1");        diagramDTO.setName("图表");        Diagram diagram = modelMapper.map(diagramDTO, Diagram.class);    }
使用开源库MapStruct

MapStruct也是Java中另外一个用于映射对象很流行的开源工具。它是在编译阶段生成对应的映射代码,相对于ModelMapper底层放射的方案,性能更好。

@Mapperpublic interface DiagramMapper {    DiagramMapper INSTANCE = Mappers.getMapper(DiagramMapper.class);    DiagramDTO toDTO(Diagram diagram);    Diagram toEntity(DiagramDTO diagram);}private static void testMapStruct() {    DiagramDTO diagramDTO = new DiagramDTO();    diagramDTO.setId("3em3dgqsgmn0");    diagramDTO.setCode("d1");    diagramDTO.setName("图表");    Diagram diagram = DiagramMapper.INSTANCE.toEntity(diagramDTO);}
DiagramMapper接口使用了@Mapper注解,用来表明使用MapStruct处理MapStruct中更多高级特性大家自己探索一下。总结

小结一下,对象在不同层之间进行转换映射,很不建议使用BeanUtil.copyProperties这种方式,更加推荐使用原生的set, get方式,不容易出错。当然这不是将BeanUtil.copyProperties一棒子打死,毫无用武之地,在特定场景,比如方法内部对象的转换等影响小的范围还是很方便的,如果你有其他的想法,也可以留下你的想法,一起探讨交流。

欢迎关注个人公众号【JAVA旭阳】交流学习!!

热门推荐

文章排行

  1. 2023-04-16麻了,不要再动不动就BeanUtil.copyProperties!!!-全球新动态
  2. 2023-04-16天天微头条丨“让每位考生都有平等的机会,不为其他非能力因素所限”
  3. 2023-04-16塔克:保罗-里德上半场没能量 中场时我骂了他&他下半场复苏了
  4. 2023-04-16天天即时看!男女之间的电灯泡是什么意思_电灯泡是什么意思
  5. 2023-04-15美国“泄密门”嫌疑人首次出庭 每日快报
  6. 2023-04-15海澜社区开展“弘扬生态文明理念 传递环境法律法规”活动
  7. 2023-04-15【大国基理】在“这里”,感受天津基层治理速度
  8. 2023-04-15非法App幕后操作!警方破获制售涉诈软件案 8人落网-焦点简讯
  9. 2023-04-15焦点热文:免疫球蛋白一针多少钱_狂犬免疫球蛋白必须打吗
  10. 2023-04-15天天讯息:魔兽世界盗贼橙色匕首外观_魔兽世界盗贼橙色匕首任务的详细流程是什么样的
  11. 2023-04-15【全球快播报】坚朗五金计划定增募资不超19.9亿元 下游客户需求减少仍坚持扩产
  12. 2023-04-15天天通讯!ESPN专家组预测首轮:湖熊难分伯仲 太阳全票晋级 勇士压倒性优势
  13. 2023-04-15世界观察:广交会15日开展 参展企业数量创新高
  14. 2023-04-15【新视野】千湖之省自驾游视频_千湖之省
  15. 2023-04-15儋州市公安局开展“预防校园欺凌·共建平安校园”主题教育宣讲活动
  16. 2023-04-15今年全省实现百万农业转移人口在城镇落户-当前简讯
  17. 2023-04-14【环球财经】新加坡金管局维持货币政策不变 称现有政策仍有效力_全球视讯
  18. 2023-04-14长虹美菱:一季度净利润同比预增1939%-2522% -世界时快讯
  19. 2023-04-14环球速看:山东省纪委监委公开曝光5起损害营商环境典型问题
  20. 2023-04-14特雷-杨:球队拼抢篮板很出色 我们的运动能力无疑以此展现出来