欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java使用BeanUtils.copyProperties踩坑經(jīng)歷

 更新時間:2021年05月26日 08:31:41   作者:申城異鄉(xiāng)人  
最近在做個項目,踩了個坑特此記錄一下,本文主要介紹了使用BeanUtils.copyProperties踩坑經(jīng)歷,需要的朋友們下面隨著小編來一起學習學習吧

1. 原始轉(zhuǎn)換

提起對象轉(zhuǎn)換,每個程序員都不陌生,比如項目中經(jīng)常涉及到的DO、DTO、VO之間的轉(zhuǎn)換,舉個例子,假設現(xiàn)在有個OrderDTO,定義如下所示:

public class OrderDTO {
    private long id;

    private Long userId;

    private String orderNo;

    private Date gmtCreated;

    // 省略get、set方法
}

有個OrderVO,定義如下所示:

public class OrderVO {
    private long id;

    private long userId;

    private String orderNo;

    private Date gmtCreated;
  
  	// 省略get、set方法
}

如果不使用任何轉(zhuǎn)換工具,代碼是下面這樣的:

public static void main(String[] args) {
    OrderDTO orderDTO = new OrderDTO();
    orderDTO.setId(1L);
    orderDTO.setUserId(123L);
    orderDTO.setOrderNo("20210518000001");
    orderDTO.setGmtCreated(new Date());

    OrderVO orderVO = new OrderVO();
    orderVO.setId(orderDTO.getId());
    orderVO.setUserId(orderDTO.getUserId());
    orderVO.setOrderNo(orderDTO.getOrderNo());
    orderVO.setGmtCreated(orderDTO.getGmtCreated());

    System.out.println(orderVO.getId());
    System.out.println(orderVO.getUserId());
    System.out.println(orderVO.getOrderNo());
    System.out.println(orderVO.getGmtCreated());
}

運行結(jié)果:

2. 使用BeanUtils.copyProperties轉(zhuǎn)換

因為項目中類似上面的轉(zhuǎn)換多而繁瑣,所以很多公司的項目中會使用Spring框架里的BeanUtils.copyProperties來做對象轉(zhuǎn)換,代碼如下所示:

OrderVO orderVO = new OrderVO();
BeanUtils.copyProperties(orderDTO, orderVO);

一行代碼搞定,很方便,運行結(jié)果也和原來一模一樣。

不過這個工具帶來便利的同時,也帶來了很多問題,稍微不注意就會踩坑,接下來就總結(jié)下使用這個工具常見的幾個坑。

3. 踩坑經(jīng)歷

3.1 包裝類型轉(zhuǎn)基本類型問題

java.lang.IllegalArgumentException

細心的你可能會發(fā)現(xiàn),OrderDTO中的userId字段,我定義的是Long類型:

而OrderVO中的userId字段,我定義的是long類型:

然后我們運行下下面所示的代碼:

public static void main(String[] args) {
    OrderDTO orderDTO = new OrderDTO();
    orderDTO.setId(1L);
    orderDTO.setUserId(null);
    orderDTO.setOrderNo("20210518000001");
    orderDTO.setGmtCreated(new Date());

    OrderVO orderVO = new OrderVO();
    BeanUtils.copyProperties(orderDTO, orderVO);
}

會看到代碼拋了java.lang.IllegalArgumentException異常:

3.2 空格問題

假設OrderVO的orderNo字段,是用戶自定義的,用戶不小心輸入了空格,使用BeanUtils.copyProperties后,空格會帶入到OrderDTO的orderNo字段,如果不小心,就會把臟數(shù)據(jù)落到數(shù)據(jù)庫(而我們希望的是去除空格再落庫的),造成一系列后續(xù)問題:

public static void main(String[] args) {
    OrderVO orderVO = new OrderVO();
    orderVO.setId(1L);
    orderVO.setUserId(123L);
    // 模擬空格場景
    orderVO.setOrderNo(" 20210518000001 ");
    orderVO.setGmtCreated(new Date());

    OrderDTO orderDTO = new OrderDTO();
    BeanUtils.copyProperties(orderVO, orderDTO);

    System.out.println(orderDTO.getOrderNo());
}

運行結(jié)果:

3.3 查找不到字段引用

使用BeanUtils.copyProperties后,會看到字段并沒有引用,其實是有用到的,如下圖所示:

有些小伙伴在看代碼時,看到字段沒有地方引用,可能就忍不住想刪掉,結(jié)果就導致真正使用該字段的地方取不到值,產(chǎn)生bug。

3.4 前端誤傳字段,直接把數(shù)據(jù)庫覆蓋了

如果接口定義的比較嚴謹,理論上是不應該存在這種情況的,不過凡事總有特殊,這里舉個接口不嚴謹導致數(shù)據(jù)被覆蓋的例子。

假如OrderVO和OrderDTO有如下2個字段:

/**
 * 已收金額
 * 單位:分
 */
private Long receivedAmount;

/**
 * 備注
 */
private String remark;

正常情況下,后端只應該使用前端傳遞的remark字段,receivedAmount字段不應該使用,但假如用戶修改訂單備注時,前端不小心傳遞了receivedAmount字段,并且賦值為null,這時使用BeanUtils.copyProperties后,OrderDTO里的receivedAmount字段就也為null,如果后端不知道前端傳遞了這個字段并且操作DB不夠嚴謹,就會導致訂單的已收金額被清空,很恐怖,而且不好排查原因。

4. 插件推薦

雖然BeanUtils.copyProperties工具提供了便利,但帶來的問題也很多,因此很多公司(包含我現(xiàn)在所在的公司)都禁止在項目中使用該工具。

但重復的寫對象轉(zhuǎn)換,實在是太繁瑣,效率太低了,這里推薦一個IDEA的插件GenerateAllSetter,可以一鍵生成對象的set方法,非常方便,如下圖所示:

插件使用:

在需要生成set方法的對象上,按快捷鍵Option+Enter(Windows是Alt+Enter),會看到下圖所示的選項:

點擊后會自動生成所有字段(沒有默認值)的賦值語句:

如果生成賦值語句時想帶默認值,可以使用另一個選項:

效果如下所示:

到此這篇關于java使用BeanUtils.copyProperties踩坑經(jīng)歷的文章就介紹到這了,更多相關BeanUtils.copyProperties踩坑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java8中Optional的使用方法詳解

    Java8中Optional的使用方法詳解

    這篇文章主要介紹了Java8中Optional的使用方法詳解,傳統(tǒng)的寫代碼方式經(jīng)常會遇到NullPointerException,這就需要我們在代碼中經(jīng)常判空,而判空的寫法又會顯得很累贅,這里就可以用到Optional來簡化代碼,需要的朋友可以參考下
    2024-01-01
  • springboot中@Async默認線程池導致OOM問題

    springboot中@Async默認線程池導致OOM問題

    這篇文章主要介紹了springboot中@Async默認線程池導致OOM問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • SpringBoot FreeWorker模板技術解析

    SpringBoot FreeWorker模板技術解析

    這篇文章主要介紹了SpringBoot FreeWorker模板技術解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 深入剖析理解AsyncGetCallTrace源碼底層原理

    深入剖析理解AsyncGetCallTrace源碼底層原理

    這篇文章主要為大家介紹了AsyncGetCallTrace源碼的深層原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-02-02
  • Java設計模式之中介者模式(Mediator Pattern)簡介

    Java設計模式之中介者模式(Mediator Pattern)簡介

    這篇文章主要介紹了Java設計模式之中介者模式(Mediator Pattern),需要的朋友可以參考下
    2014-07-07
  • SpringBoot?配置文件總結(jié)

    SpringBoot?配置文件總結(jié)

    SpringBoot中提供一個全局的配置文件:application.properties,這個配置文件的作用就是,允許我們通過這個配置文件去修改Spring?Boot自動配置的默認值,本文詳細總結(jié)了SpringBoot配置文件,文中有詳細的代碼示例,感興趣的同學可以參考下
    2023-05-05
  • Java枚舉類型enum的詳解及使用

    Java枚舉類型enum的詳解及使用

    這篇文章主要介紹了Java枚舉類型enum的詳解及使用的相關資料,需要的朋友可以參考下
    2017-05-05
  • java中&與&&的區(qū)別

    java中&與&&的區(qū)別

    本文主要介紹了java中&與&&的區(qū)別,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • feign調(diào)用返回object類型轉(zhuǎn)換方式

    feign調(diào)用返回object類型轉(zhuǎn)換方式

    這篇文章主要介紹了feign調(diào)用返回object類型轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 利用Java實現(xiàn)文件鎖定功能

    利用Java實現(xiàn)文件鎖定功能

    這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)文件鎖定功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-08-08

最新評論