最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1. 原始轉(zhuǎn)換

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

public class OrderDTO {
    private long id;

    private Long userId;

    private String orderNo;

    private Date gmtCreated;

    // 省略get、set方法
}

有個(gè)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());
}

運(yùn)行結(jié)果:

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

因?yàn)轫?xiàng)目中類似上面的轉(zhuǎn)換多而繁瑣,所以很多公司的項(xiàng)目中會(huì)使用Spring框架里的BeanUtils.copyProperties來(lái)做對(duì)象轉(zhuǎn)換,代碼如下所示:

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

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

不過(guò)這個(gè)工具帶來(lái)便利的同時(shí),也帶來(lái)了很多問(wèn)題,稍微不注意就會(huì)踩坑,接下來(lái)就總結(jié)下使用這個(gè)工具常見(jiàn)的幾個(gè)坑。

3. 踩坑經(jīng)歷

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

java.lang.IllegalArgumentException

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

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

然后我們運(yùn)行下下面所示的代碼:

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

會(huì)看到代碼拋了java.lang.IllegalArgumentException異常:

3.2 空格問(wèn)題

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

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

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

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

運(yùn)行結(jié)果:

3.3 查找不到字段引用

使用BeanUtils.copyProperties后,會(huì)看到字段并沒(méi)有引用,其實(shí)是有用到的,如下圖所示:

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

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

如果接口定義的比較嚴(yán)謹(jǐn),理論上是不應(yīng)該存在這種情況的,不過(guò)凡事總有特殊,這里舉個(gè)接口不嚴(yán)謹(jǐn)導(dǎo)致數(shù)據(jù)被覆蓋的例子。

假如OrderVO和OrderDTO有如下2個(gè)字段:

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

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

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

4. 插件推薦

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

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

插件使用:

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

點(diǎn)擊后會(huì)自動(dòng)生成所有字段(沒(méi)有默認(rèn)值)的賦值語(yǔ)句:

如果生成賦值語(yǔ)句時(shí)想帶默認(rèn)值,可以使用另一個(gè)選項(xiàng):

效果如下所示:

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

相關(guān)文章

  • java必學(xué)必會(huì)之equals方法

    java必學(xué)必會(huì)之equals方法

    java必學(xué)必會(huì)之equals方法,equals方法是 java.lang.Object 類的方法,想要了解更多關(guān)于equals方法的朋友,可以參考下文
    2015-12-12
  • java組件commons-fileupload文件上傳示例

    java組件commons-fileupload文件上傳示例

    這篇文章主要為大家詳細(xì)介紹了java組件commons-fileupload實(shí)現(xiàn)文件上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Spring security BCryptPasswordEncoder密碼驗(yàn)證原理詳解

    Spring security BCryptPasswordEncoder密碼驗(yàn)證原理詳解

    這篇文章主要介紹了Spring security BCryptPasswordEncoder密碼驗(yàn)證原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式

    詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式

    目前Java開(kāi)發(fā)包中包含了對(duì)動(dòng)態(tài)代理的支持,但是其實(shí)現(xiàn)只支持對(duì)接口的的實(shí)現(xiàn)。這篇文章主要介紹了詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式 ,有興趣的可以了解一下。
    2016-11-11
  • java發(fā)送post請(qǐng)求使用multipart/form-data格式文件數(shù)據(jù)到接口代碼示例

    java發(fā)送post請(qǐng)求使用multipart/form-data格式文件數(shù)據(jù)到接口代碼示例

    這篇文章主要介紹了java發(fā)送post請(qǐng)求使用multipart/form-data格式文件數(shù)據(jù)到接口的相關(guān)資料,文中指定了數(shù)據(jù)編碼格式為UTF-8,并強(qiáng)調(diào)了所需依賴工具類,需要的朋友可以參考下
    2024-12-12
  • Java經(jīng)典設(shè)計(jì)模式之裝飾器模式解析

    Java經(jīng)典設(shè)計(jì)模式之裝飾器模式解析

    這篇文章主要介紹了Java經(jīng)典設(shè)計(jì)模式之裝飾器模式解析,裝飾器模式主要解決繼承關(guān)系過(guò)于復(fù)雜的問(wèn)題,通過(guò)組合來(lái)替代繼承,指在不改變現(xiàn)有對(duì)象結(jié)構(gòu)的情況下,動(dòng)態(tài)地給該對(duì)象增加一些職責(zé)(即增加其額外功能)的模式,需要的朋友可以參考下
    2023-08-08
  • Java中Spring MVC接收表單數(shù)據(jù)的常用方法

    Java中Spring MVC接收表單數(shù)據(jù)的常用方法

    Spring MVC是Spring框架中的一個(gè)模塊,用于開(kāi)發(fā)基于MVC(Model-View-Controller)架構(gòu)的Web應(yīng)用程序,它提供了一種輕量級(jí)的、靈活的方式來(lái)構(gòu)建Web應(yīng)用,同時(shí)提供了豐富的功能和特性,本文給大家介紹了Spring MVC接收表單數(shù)據(jù)的方法,需要的朋友可以參考下
    2024-05-05
  • maven模塊化開(kāi)發(fā)部署實(shí)現(xiàn)方案

    maven模塊化開(kāi)發(fā)部署實(shí)現(xiàn)方案

    有些用戶有定制化需求,需要添加新的模塊功能,因此需要平臺(tái)主體功能迭代的同時(shí),非主體功能和定制化功能插件化,本文給大家介紹maven模塊化開(kāi)發(fā)部署實(shí)現(xiàn)方案,感興趣的朋友一起看看吧
    2024-01-01
  • Java 泛型總結(jié)及詳解

    Java 泛型總結(jié)及詳解

    這篇文章主要介紹了Java 泛型的相關(guān)資料,并附簡(jiǎn)單實(shí)例代碼,需要的朋友可以參考下
    2016-09-09
  • 因Spring AOP導(dǎo)致@Autowired依賴注入失敗的解決方法

    因Spring AOP導(dǎo)致@Autowired依賴注入失敗的解決方法

    這篇文章主要給大家介紹了因Spring AOP導(dǎo)致@Autowired依賴注入失敗的解決方法,文中通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07

最新評(píng)論

泰和县| 宾川县| 奈曼旗| 泰兴市| 铁岭市| 五寨县| 庆阳市| 巴东县| 东至县| 襄汾县| 莱阳市| 珲春市| 营山县| 乌鲁木齐县| 米易县| 阿拉善右旗| 温泉县| 瑞昌市| 安福县| 中阳县| 肥东县| 分宜县| 宁阳县| 邵东县| 道孚县| 临洮县| 洛宁县| 景德镇市| 商南县| 大理市| 舒城县| 海城市| 辽宁省| 调兵山市| 阳泉市| 白水县| 苍山县| 永济市| 渭南市| 射阳县| 揭西县|