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

这篇具有很好参考价值的文章主要介绍了麻了,不要再动不动就BeanUtil.copyProperties!!!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近项目上要求升级一个工具包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!!!

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

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

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

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

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

分析探讨

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

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

推荐方案

  1. 原始的getset方式

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

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

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

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

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

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

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

欢迎关注个人公众号【JAVA旭阳】交流学习!!文章来源地址https://www.toymoban.com/news/detail-415089.html

到了这里,关于麻了,不要再动不动就BeanUtil.copyProperties!!!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决Hutool BeanUtil 拷贝异常场景

    我们使用的是Hutool工具包的cn.hutool.core.bean.BeanUtil解决对象拷贝复制场景。 工作中我们经常做这样工作:比如说将VO复制成DO。 VO、DTO、DTO、BO,RequestDTO互相转化。  我们服务作为系统的开放平台应用,统一维护管理第三方平台API接口。比如企业微信接口。而我们使用开源项目

    2024年02月03日
    浏览(103)
  • 父类对象的属性直接赋值给子类对象(使用copyProperties中的方法copyProperties)

    BeanUtils.copyProperties() 是 Apache Commons BeanUtils 包中提供的一个方法,用于将一个 JavaBean 对象的属性值赋值到另一个 JavaBean 对象中。该方法可以简化 JavaBean 之间的属性复制过程,避免手动编写大量的赋值代码。 以下是 BeanUtils.copyProperties() 方法的基本用法: 在上面的例子中,首

    2024年02月15日
    浏览(43)
  • Spring学习笔记(一)【BeanUtils.copyProperties方法】

    简单地说,拷贝就是将一个类中的属性拷贝到另一个中,对于BeanUtils.copyProperties来说, 必须保证属性名和类型是相同的,因为它是根据get和set方法来赋值的 1.1、 浅拷贝 浅拷贝对于 基本数据类型 就是直接进行 值传递 ,在内存的另一个空间内存放,修改这个值不会影响到拷

    2024年01月16日
    浏览(34)
  • Hutool BeanUtil工具使用及SQL中AND与OR优先级解析

    本文深入探讨了Hutool工具包中的BeanUtil工具的使用,以及SQL查询语句中AND和OR逻辑运算符的优先级问题。

    2024年02月10日
    浏览(61)
  • 面试被问麻了....

    前几天组了一个软件测试面试的群,没想到效果直接拉满,看来大家对面试这块的需求还是挺迫切的。昨天我就看到群友们发的一些面经,感觉非常有参考价值,于是我就问他还有没有。 结果他给我整理了一份非常硬核的面筋,打开一看,也太多了,差点麻了。。。 不过,

    2024年02月05日
    浏览(42)
  • 面试被问麻了...

    前几天组了一个软件测试面试的群,没想到效果直接拉满,看来大家对面试这块的需求还是挺迫切的。昨天我就看到群友们发的一些面经,感觉非常有参考价值,于是我就问他还有没有。 结果他给我整理了一份非常硬核的面筋,打开一看,也太多了,差点麻了。。。 不过,

    2024年02月07日
    浏览(47)
  • 麻了,真的不想做测试了...

    有不少技术友在测试群里讨论,近期的面试越来越难了,要背的八股文越来越多了,考察得越来越细,越来越底层,明摆着就是想让我们徒手造航母嘛!实在是太为难我们这些测试工程师了。 这不,为了帮大家节约时间,给大家搞来了今年上半年碰到的软件测试面试题合集,

    2024年02月05日
    浏览(37)
  • 面试真的被问麻了......

    前几天组了一个软件测试面试的群,没想到效果直接拉满,看来大家对面试这块的需求还是挺迫切的。昨天我就看到群友们发的一些面经,感觉非常有参考价值,于是我就问他还有没有。 结果他给我整理了一份非常硬核的面筋,打开一看,也太多了,差点麻了。。。 不过,

    2024年02月05日
    浏览(42)
  • @Accessors(chain = true)导致BeanUtils.copyProperties失效问题的排查思路

    @Accessors是由lombok提供的一个注解,chain = true的作用是使成员属性的set方法不再返回void,而是返回对象本身,从而实现链式赋值。效果如下: 然而加了该注解后,我发现 org. apache.commons .beanutils.BeanUtils.copyProperties(final Object dest, final Object orig)方法失效。 经试验发现,当我用 

    2024年02月09日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包