首页 今日头条正文

帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博

布景

最近项目中在和第三方进行联调一个接口,咱们这边发送h煮avt亚洲热tp恳求给对方,然后接纳对方的回应,代码都是老代码。is酒徒依据注释,对方的SDK中写好的Request类有一个无法序列化的bug,所以这边从头写了一个Request类,根本特点都是相同的,可是重点是有一个特点是静态内部类,还有两个是list特点,姑侄通奸类似于下面这样:

private List orders;

private AddRequest.Ticket ticket;

private List payments;

AddRequest便是咱们自己重写的恳求类,他们SDK中的恳求类是MixAddRequest,咱们拼装好恳求参数后使用Spring的BeanUtils的copyPropertie帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博s办法将AddRequest中的特点复制到MixAddReques帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博t,然后发送恳求。到此为止,照理说全部完美

成果恳求失利,纳尼?对方说短少一个必要的字段,参数校验不通过,一查字段称号,是Ticket这个类里边的某个字段,赶忙看代码,心里充溢对老代码的自傲,想着一定是哪里搞错了,或许是lx808他们那儿悄悄动帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博了代码,把字段从艳婢可选改为了必选,嘿嘿

公然在代码里找到了设置的当地,这下应该是他们的问题确信无疑了,再开一把调试,预备宣判他们的死刑。成果发现发给他们的恳求便是没有这个字段。。。中心只要一个Spring的copy特点的办法,其时觉得很怪异

由于中心只要这么一行代码,玄机必定在这儿边,开始怀疑是两个静态内部类不同导六花簿本致,所以自己写Demo,预备搞一把这个BeanUtils的copyProperties办法,写了两个类和一个Main,@Data和@ToString是lombok插件的注解,这儿用来主动生成getter和setter办法以及toString办法

@ToString@Datapublic class CopyTest1 { publ游澜ic String outerName; pub重生八极拳国术抱丹lic CopyTest1.InnerClass innerClass; public List clazz; @ToString @Data public static class InnerClass { public String I福利社区nnerName; }}
@ToString@Datapublic class CopyTest2 { public String outerName; public CocohensionpyTest2.InnerClass innerClass; public List clazz; @ToString @D朱梓超ata public static class InnerClass { public String 官员不雅观InnerNamexianrenba; }}
CopyTest1 test1 = new CopyTest1();test1.outerName = "hahaha";CopyTest1.InnerClass innerClass = new CopyTest1.InnerClass();innerClass.InnerName = "hohoho";test1.in青果直播吧nerClass = innerClass;System.out.println(test1.toString());CopyTest2 test2 = new CopyTest2();BeanUtils.copyProperties(test1, test2);System.out.println(test2.toString());

这儿遇到了第一个坑,一开始图省劲,特点写为public,想着省掉了getter和setter办法,没加@Data注解,成果运转完test2一切特点都为null,一个都没copy曩昔,加上@Data持续跑,公然,根本特点(String)仿制曩昔了,可是内部类在test2中仍是null。那就验证了真的是内部类的问题,有点不敢相信自己的眼睛,究竟线上跑了这么久的代码。。。

知道了问题,总要想着怎样处理吧,所以需求独自设置一下内部类,独自copy,假如内部类的bean特点较多或许递归的bean特点许多,那能够自己封装一个办法,用于递归复制,我这儿只要一层,所以直接额定copy一次

CopyTest1 test1 = new CopyTest1();test1.outerName = "ha奇亚籽我国禁售原因haha";CopyTest1.InnerClass innerClass = new CopyTest1.InnerClass();innerClass.InnerName = "hohoho";test1.innerClass = innerClass;System.out.println(test1.toString());CopyTest2 test2 = new CopyTest2();test2.innerClass = new CopyTest2.InnerClass();BeanUtils.copyProperties(test1, test2);BeanUtils.copyProperties(test1.innerC帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博lass, test2.innerClass);System.out.println(test2.toString());

记住内部类的特点也是要有sette帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博r办法的,否则也会导致copy失利,我们还记住我最初说到还有两个List特点的吧,为什么要说到这个呢?你蜜中妻猜

其实list里边的两个类也都是重写的内部类,他们也是不同的,其时他们却顺畅copy曩昔了,为什么呢?由于java的泛型只在编译期起作用,在运转期,list特点便是一个寄存Object的调集,在copy后,MixAddRequest的orders特点其实是一个帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博Order类的集季鹍之嗣合,但却不是自己内部类的调集,是AddRequest的内部类Order的调集,但由于对方是解析json的,所以没有发生过错。。。

总结

1.Spring的BeanUtils的CopyProperties办法需求对应的特点有getter和setter办法

2.假如存在特点完全相同的内部类,可是不是同一个内部类,即别离归于各自的内部类,则spring会以为特点不同,不会copy瞋目切齿;

3.泛型只在编译期起作用,不能依托泛型来做运转期的约束;

4.最终,sprin帕劳,坑啊,Spring的BeanUtils是这样用的,为啥会出bug?,付辛博g和apache的copy特点的办法源和意图参数的方位正好相反,所以导包和调用的时分都要留意一下。

最终的最终

附上spring的源码,getWriteMethod是jdk的办法,会去取set最初的办法,所以没有setter办法是不可滴。

private static void copyProperties(Object source, Object target, @Nullable C
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。