麻了,不要再动不动就BeanUtil.copyProperties

news2024/11/26 12:14:54

前言

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

事件回顾

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

  1. 数据传输对象
@Data
@ToString
public class DiagramDTO {

    // 前端生产的字符串id
    private String id;

    private String code;

    private String name;
}
复制代码
  1. 数据实体对象
@Data
@ToString
public class Diagram {

    private Integer id;

    private String code;

    private String name;
}
复制代码
  1. 业务逻辑
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的方式压根无法在编译阶段发现,更别提修改的影响范围了,这就只能把风险暴露到生产上去了。那有什么更好的方法呢?

推荐方案

  1. 原始的getset方式

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

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

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

  1. 使用开源库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);
    }
复制代码
  1. 使用开源库MapStruct

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

@Mapper
public 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一棒子打死,毫无用武之地,在特定场景,比如方法内部对象的转换等影响小的范围还是很方便的,如果你有其他的想法,也可以留下你的想法,一起探讨交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/423955.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hudi集成Flink-写入方式

文章目录一、CDC 入湖1.1、[开启binlog](https://blog.csdn.net/wuxintdrh/article/details/130142601)1.2、创建测试表1.2.1、创建mysql表1.2.2、将 binlog 日志 写入 kafka1、使用 mysql-cdc 监听 binlog2、kafka 作为 sink表3、写入sink 表1.2.3、将 kakfa 数据写入hudi1、k…

ERTEC200P-2 PROFINET设备完全开发手册(4-2)

4.2 XHIF接口实验 4.2.1写入单片机固件 首先按照下图连接设备 用JLINK 20Pin JTAG连接4 Pin SWD可以采用转接板 单片机的参考程序是用ST的CubeIDE生成的,目前的版本是1.7.0。打开安装后的CubeIDE,在菜单中选择“File->Import“ 选择“Existing Proj…

企业信息化建设都包括哪些方面?

随着大数据技术的发展,时代的发展要求企业转变管理模式、建立信息化管理机制,同时也是提高工作、管理效率,促进企业战略性发展的重要保障。 企业信息化是将信息技术应用于企业发展实践中的一个动态过程,即通过挖掘先进的管理理念…

高可靠多层板制造服务再获认可!华秋荣获创想三维优秀质量奖

4月10日,创想三维2023年度战略供应商大会在惠州成功举办,高可靠多层板制造商华秋出席了本次活动并取得了《优秀质量奖》一奖项。 大会现场,创想三维董事长陈春指出公司的持续发展与供应链高质量的交付息息相关。作为创想三维主力PCB供应商&am…

【亲测有效】更新了WIN11之后 右键无 新建WORD,PPT,EXCEL 选项 问题 解决方案

原本正常的正版系统,在昨天4月自动更新安装之后,发现右键找 不到新建文档了,word,ppt,excel都不见了。 看了网上大神的方法 Win11安装了Office右键没有新建Excel选项怎么办? - 知乎 可以解决一部分 官方解决方案,亲…

李宏毅2021春季机器学习课程视频笔记14-Transformer

Transformer Transformer实际上就是变形金刚,其与Bert实际类似。其实际上就是一个Sequence-to-Sequence的模型,其输出的长度并不是由人为指定,而是由机器自行确定。 Transformer的基本结构,如上图所示,主要由一个Encod…

AS01/AS02/AS03 创建定制屏幕字段

本文简介:在sap标准屏幕上,增加客户定制的屏幕字段。 操作步骤: 1、在创建资产卡片AS01时,界面需要输入客户定制的字段,如下图方框所示 2、查看增强点,事务码:SMOD AIST002 3、创建增强项目…

M1 M2上能安装上Autocad 2024 Mac 中文版吗 autocad m1 m2版本有啦 终于支持Ventura 13x了

AutoCAD是一款强大的工具,适合于各种领域的设计和绘图。它具有二维图形和三维建模功能、多种文件格式支持、自定义命令和样式、批处理和脚本等特点,可以帮助用户实现高质量的设计和建模。同时,还支持云端存储和共享,方便用户随时随…

【Linux】-- 进程概念的引入

目录 硬件 冯诺依曼体系结构 冯诺依曼体系结构推导 重点概念 网络数据流向 软件 操作系统(Operator System - OS) 概念 定位 进程内核数据结构PCB(task_struct) 通过系统调用创建进程-fork初始 fork基本用法 使用if进行分流 查看运行效果 …

Python每日一练(20230417)

目录 1. 最大间距 🌟🌟🌟 2. Z 字形变换 🌟🌟 3. 买卖股票的最佳时机 II 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练…

通过Android Studio自制.9.png启动页图片 - uniapp启动界面设置Android启动图片设置

效果图 实现步骤 下载安装JDK 参考Oracle官网: https://www.oracle.com/java/technologies/javase/upgrade.html 再跳转到JavaSE Upgrade下载页面:Java Downloads | Oracle 配置JDK: 假设jdk安装位置是D:\Program Files\Java\jdk-18.0.1.1 …

CDH6.3.2大数据集群生产环境安装(八)之各组件参数调优,yarn参数调优,hdfs参数调优等

yarn资源调优 主要涉及到了ResourceManager、NodeManager这几个概念,相关的优化也要紧紧围绕着这几方面来开展。这里还有一个Container的概念,现在可以先把它理解为运行map/reduce task的容器 28.1. 内存 堆栈等配置  原值  调优值

java并发编程之美第一章并发编程基础(读书笔记)

1–50面 java并发编程基础 什么是线程 进程: 是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位 线程: 是进程的一次执行路径,一个进程至少有一个线程,进程中的多个线程共享进程的资源. 线程是CPU分配的基本单位 栈: 每个线程都有自己的栈资源,用…

02_CCC3.0数字钥匙_SPAKE2+执行流程

02_CCC3.0数字钥匙_SPAKE2执行流程Vehicle OEM Server:派生salt、L和w0;这三个参数需要服务器给到车辆端的,所以需要在服务器事先生成。用于与车辆端的做SPAKE2验证。DK Scrypt(pwd, s, Nscrypt, r, p, dkLen); z0 DK[0 : 320]…

判断环形链表是否有环??返回环形链表的入口点

给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(…

IDEA插件-MavenHapler

1.安装Maven Helper Maven Helper 是 IntelliJ IDEA 中的一个插件,可以帮助您管理 Maven 依赖项。它可以帮助您更容易地删除不再需要的依赖项,查看依赖项的冲突,以及执行其他有关 Maven 依赖项的操作。 打开 IDEA 设置页面: 在插…

gpu超频超额训练导致电源关机

详细原理参见: 离显卡功耗实标还有多远?峰值功耗与电源关系终结篇 – FCPOWERUP极电魔方 和 【硬件科普】如何合理科学的选择电源功率的大小?_哔哩哔哩_bilibili 本人的1250w电源截图: 分析: 12V输出分了6路&#xff…

游戏逆向_Android读写游戏内容

一、背景 Android外挂的实现,需要涉及相应游戏内容的读写。读写的游戏内容包括代码和数据 针对不同的读写对象,通用的步骤就是寻找对象地址(位置)→获取相应权限→读写。下面将更详细介绍下相关实现。 二、实现方式 实现方式可…

了解最新的Android开发趋势和技术的秘诀

前言 当前,Android开发市场已经相当成熟,并且在全球范围内都非常活跃。Android是全球最受欢迎的移动操作系统之一,自Android开源以来,它已经改变了移动技术。市场上大量的企业和开发者都在积极地跟进、深入研究和开发Android系统…

大数据Flink进阶(十二):Flink本地模式开启WebUI

文章目录 Flink本地模式开启WebUI 一、在Flink 项目中添加本地模式 WebUI的依赖