`
Jen
  • 浏览: 57527 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

关于BeanUtils拷贝null属性的问题

    博客分类:
  • java
阅读更多

关于BeanUtils拷贝null属性的问题

jen wang

 

       帮同事查看物流发货问题时,发现BeanUtilscopy null属性时会有一些问题。现在总结一下现象、原因和解决方法。

问题现象

       1.当源对象(a)中存在一个java.sql.Date类型的属性并且值为null,目标对象(b)中也存在这个同名同类型的属性。把a对象属性值copybBeanUtils.copyProperties(b, a);会抛出异常;

       2.当源对象(a)中存在一个java.sql.Date类型的属性并且值为null,目标对象(b)不存在这个同名同类型的属性,copy时没问题。

原因

       查看BeanUtils源代码,定位到org.apache.commons.beanutils.BeanUtilsBean.copyProperties(Object dest, Object orig)方法的关键代码,

 

public void copyProperties(Object dest, Object orig)

        throws IllegalAccessException, InvocationTargetException {

   

    ……

    if (getPropertyUtils().isReadable(orig, name) &&

         getPropertyUtils().isWriteable(dest, name)) {

           try {

                Object value =

                getPropertyUtils().getSimpleProperty(orig, name);

                copyProperty(dest, name, value);

           } catch (NoSuchMethodException e) {

                        ; // Should not happen

           }

    }

    ……

}

 

isWriteable这一行,当目标对象没有相应的属性时不进行copy,所以不会有问题(现象2)

再看copyProperty方法的关键代码,



 

引起现象1的代码为value = converter.convert(type, value);这行,这里会抛出一个类型转换错误。转化器在转化时报错,需要找出这个转化器,继续往下看代码,ConvertUtilsBean.lookup(Class clazz)方法,



 

再看converters中注册的转化器方法ConvertUtilsBean.deregister()的关键代码,



 
 

找到了相应的转化器SqlDateConverter,异常就在这个SqlDateConverter转化类型时抛出,当java.sql.Date类型的属性值为null时抛异常。



 

解决方法

<!--[if !supportLists]-->l  <!--[endif]-->方法一

       convert方法可以看出只要想办法把useDefaultdefaultValue设值就能解决,SqlDateConverter的另外一个构造方法可以设置这两个值,问题是从哪里把这个自己构造的converter 注册进去。从BeanUtilsBeanUtilsBean再到ConvertUtilsBean的找,发现都是写死的调用ConvertUtilsBean.deregister()方法注册的,最后发现ConvertUtilsBean有个register(Converter converter, Class clazz)方法可以注册,而ConvertUtilsBean又是在BeanUtilsBeannew出来的,那么只要获取到这个ConvertUtilsBean即可,BeanUtilsBean提供了获取的方法。因此在BeanUtils.copyProperties(b, a);加上下面这句代码即可

BeanUtilsBean.getInstance().getConvertUtils().register(new SqlDateConverter(null),Date.class);

另外有一个辅助类也可以,

ConvertUtils.register(new SqlDateConverter(null),Date.class);

 

<!--[if !supportLists]-->l  <!--[endif]-->方法二

    从上面copyProperty方法可以看出,只有找到注册过的转化器,才使用转化器进行对值的转化,否则直接copy value。而deregister中并没有对java.util.Date注册相应的转化器,所以把java.sql.Date改为java.util.Date也可以解决问题。

 

<!--[if !supportLists]-->l  <!--[endif]-->方法三

       java.sql.Date的转化器去掉ConvertUtils.deregister(Date.class);

 

问题延伸

       从上述分析可以看出,拷贝含有java.sql.Timejava.sql.Timestampjava.io.Filejava.net.URL等类型的null属性也会有类似的问题,使用时需要多加小心。

       在字段属性比较明确并且较少的情况下,单单为了简化代码或者使代码优雅而引入BeanUtils这种相对复杂的copy机制是否值得,需要权衡,毕竟它增加了复杂性也牺牲了一些性能的。

 

 

  • 大小: 39.1 KB
  • 大小: 11.6 KB
  • 大小: 39.4 KB
  • 大小: 23.9 KB
分享到:
评论
2 楼 yangsong158 2015-09-18  
多年后,依然还会遇到这个问题。楼主分析透彻。好评,五星
1 楼 hxc316 2011-08-16  

相关推荐

    commons-beanutils-1.9.4.jar.zip

    5. **拷贝属性**:`BeanUtils.copyProperties()`方法可以实现对象间的属性深度拷贝,这对于创建对象副本或者在不同对象间传递数据十分便利。 6. **避免空指针异常**:BeanUtils库在处理null值时会进行保护,避免因...

    BeanUtils jar包+源码

    BeanUtils的核心功能在于属性的自动类型转换和封装,它能够自动处理JavaBeans对象之间的属性拷贝,即使源对象和目标对象的属性类型不完全匹配,BeanUtils也能尝试进行类型转换。例如,将字符串转换为整型或浮点型,...

    Commons BeanUtils 1.8.3 API

    4. **空值处理**:对于null值的属性,BeanUtils提供了一种机制来处理,可以设定默认值或者忽略空值。 5. **国际化支持**:BeanUtils也与Apache Commons Locale和ResourceBundle结合,支持多语言环境下的Bean属性...

    BeanUtils工具 .jar 包

    3. **避免空指针异常**:在处理可能为空的对象或属性时,BeanUtils工具包会进行检查,如果源对象或属性为null,它不会抛出NullPointerException,而是安全地跳过,这在处理不确定的数据源时非常有用。 4. **处理...

    commons-beanutils-1.8.0-src

    BeanUtils提供的API使得我们无需直接调用这些方法,而是通过字符串形式的属性名来操作Bean的属性。 1. **属性复制(Property Copying)** BeanUtils的最显著特性是`copyProperties()`方法,它允许我们从一个对象的...

    commons-beanutils (1.7.0 -1.9.2)6个

    - **数据转换**:在数据交换或序列化过程中,BeanUtils的属性拷贝功能能帮助快速地转换数据结构。 - **框架集成**:许多Java框架如Struts、Spring等,都可能依赖`commons-beanutils`来简化对象操作。 5. **注意...

    为什么不推荐使用BeanUtils属性转换工具示例详解

    例如,在公司内部,我们曾经遇到过使用commons包的BeanUtils进行属性拷贝时性能较差的情况。后来,我们换成了Spring的BeanUtils,性能好了很多。 其次,让我们来看一下BeanUtils的风险。使用BeanUtils进行属性拷贝...

    commons-beanutils-1.8.3

    虽然BeanUtils大大提高了开发效率,但它的无条件属性复制可能导致安全问题,比如当源对象包含敏感属性时,可能会被无意间复制。因此,在使用`copyProperties()`时,需谨慎处理源对象的属性。 7. **总结** Apache ...

    commons-beanutils-core-1.8.0.jar

    虽然BeanUtils提供了极大的便利,但需要注意的是,它的属性拷贝功能可能会引发安全问题,例如在处理用户输入时未经验证就直接复制,可能会导致注入攻击。因此,使用时应确保对输入数据进行充分的校验和过滤。 六、...

    beanUtils..jar

    然而,需要注意的是,尽管BeanUtils库提供了便利,但它的无条件属性复制可能会带来安全问题,如潜在的空指针异常或者属性覆盖。因此,在使用时,开发者应确保对目标对象进行适当的初始化,并了解属性复制的潜在风险...

    apache BeanUtils

    BeanUtils在处理null值时有特别的处理方式,如果试图设置的属性不存在或者值为null,它不会抛出NullPointerException。这在处理不确定的数据源时非常有用,增强了代码的健壮性。 4. 格式转换: BeanUtils内部使用了...

    BeanUtils资源

    3. **对象拷贝**:在对象模型转换时,BeanUtils的`copyProperties()`方法可以实现深度复制,避免了手动编写大量的赋值代码。 4. **属性操作**:对于拥有大量属性的复杂Bean对象,BeanUtils可以提供一种统一且简便的...

    BeanUtils.jar

    3. **空值处理**:BeanUtils还提供了处理null值的方法,如NullAwarePropertyUtils.copyProperties(),它可以避免因源对象中属性为null而导致的目标对象抛出NullPointerException。 4. **动态属性访问**:BeanUtils...

    BeanUtils工具类

    BeanUtils的核心功能是属性的复制,它通过反射机制来实现对象之间属性值的拷贝。例如,当我们从数据库查询结果中得到一个结果集,通常会将这些结果映射到Java Bean对象上,BeanUtils可以帮助我们自动填充Bean对象的...

    Commons-beanutils.rar

    Apache Commons BeanUtils是Java开发中的一个实用工具库,它提供了对JavaBeans属性操作的强大功能,极大地简化了开发者在处理对象属性时的代码。这个压缩包"Commons-beanutils.rar"包含了从1.4到1.9的不同版本,这...

    JSP 开发之Spring BeanUtils组件使用

    Spring的BeanUtils组件为我们提供了简化属性复制的方法,比如`copyProperties`,它可以高效地将一个源对象的属性值拷贝到目标对象中去。这个过程是自动化完成的,开发者无需手动编写set方法来逐个赋值。 从给出的...

    BeanUtil框架完整包

    BeanUtil框架是一个在Java开发中常用的工具库,主要用于对象属性的获取、设置、拷贝以及类型转换等操作。它的设计目标是简化Java Bean的操作,提高代码的可读性和可维护性。这个“BeanUtil框架完整包”包含了...

    利用反射技术实现POJO值拷贝

    使用这个工具类时,假设我们有两个POJO类`UserSource`和`UserTarget`,只需要调用`BeanUtils.copyProperties(sourceUser, targetUser)`即可完成值拷贝。 虽然反射提供了一种灵活的解决方案,但需要注意其性能开销。...

    commons-beanutils-1.8.0.jar

    3. **属性复制**:BeanUtils.copyProperties()方法可以实现两个JavaBean之间属性的深拷贝或浅拷贝,大大简化了对象间的属性迁移。 4. **集合操作**:支持集合属性的处理,例如将一个数组或列表的值分配给JavaBean的...

    Java开发手册(嵩山版)灵魂15问.pdf

    Apache BeanUtils提供了便捷的属性拷贝功能,但在大规模或高性能应用中,其效率相对较低。相比其他如Spring的BeanUtils、Cglib的BeanCopier等工具,BeanUtils在处理大量对象复制时可能会导致性能瓶颈。这是因为...

Global site tag (gtag.js) - Google Analytics