对象之间属性赋值,改造BeanUtils.copyProperties()方法,属性类型不同也要转换

小可怡情 2021-03-27 09:37:14
我们知道要将DO对象转换成VO这种时候一般都用BeanUtils.copyProperties(),但是有个要求就是属性名和属性的类型都必须完全一致才行,否则该属性就不会拷贝,依旧是null(名称或者类型不同本来也就没办法拷贝)。
我们公司的VO对象里以为某种原因对象参数只能使用基本数据类型,这样DO里有Date,Bigdecimal之类的就惨了,都需要单独进行处理。于是就写了这么个工具类,也是从copyProperties这个方法里面的代码改成的,目前只写了处理Date转String,Bigdecimal转Doub,有其他转换需要的自己再添加(不然不同类型会报错的)。

package util;

import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
* @author :王可可
* @date :Created in 2021/3/27 19:07
*/
public class MyUtil {

public static void copyProperties(Object source, Object target, String dateFormat) throws InvocationTargetException, IllegalAccessException {
copy(source, dateFormat, target);
}

public static void copyProperties(Object source, Object target) throws InvocationTargetException, IllegalAccessException {
String dateFormat = null;
copy(source, dateFormat, target);
}

public static <T> T copyProperties(Object source, Class<T> targetClass) throws InvocationTargetException, IllegalAccessException, InstantiationException {
String dateFormat = null;
T target = null;
if (source != null){
target = targetClass.newInstance();
copy(source, dateFormat, target);
}
return target;
}

public static <T> T copyProperties(Object source, Class<T> targetClass, String dateFormat) throws InvocationTargetException, IllegalAccessException, InstantiationException {
T target = null;
if (source != null){
target = targetClass.newInstance();
copy(source, dateFormat, target);
}
return target;
}

public static <T> List listConverter(List list, Class<T> classT, String dateFormat) throws InvocationTargetException, IllegalAccessException, InstantiationException {
List<T> targetList = new ArrayList();
if (list != null && list.size() != 0){
Iterator var3 = list.iterator();
while(var3.hasNext()) {
Object object = var3.next();
targetList.add(copyProperties(object, classT, dateFormat));
}
}
return targetList;
}

private static void copy(Object source, String dateFormat, Object target) throws IllegalAccessException, InvocationTargetException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
if (dateFormat == null) {
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
Class<?> aClass = source.getClass();
PropertyDescriptor[] apds = BeanUtils.getPropertyDescriptors(aClass);
Class<?> bClass = target.getClass();
PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(bClass);
int n = pds.length;
for (int i = 0; i < n; ++i) {
PropertyDescriptor targetPd = pds[i];
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null) {
PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
for (int j = 0; j < apds.length; j++) {
PropertyDescriptor apd = apds[j];
if (apd.getReadMethod().getName().equals(readMethod.getName())) {
// 将对象2的属性get方法转换成对象1的get方法(获得的value的类型就是对象1的该属性的类型)
readMethod = apd.getReadMethod();
continue;
}
}
if (readMethod != null) {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
// 此处对要赋的值类型进行判断和处理
if (value.getClass().equals(Date.class)) {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
value = sdf.format(value);
} else if (value.getClass().equals(BigDecimal.class)) {
BigDecimal b = (BigDecimal) value;
value = b.doubleValue();
}
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
}
}
}
}
}
}

...全文
4434 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
专心拔剑 2021-04-14
  • 打赏
  • 举报
回复
BeanUtils 效率低啊! 推荐使用 Cglib BeanCopier
无所求者无能 2022-03-11
  • 举报
回复
@专心拔剑 推荐使用MapStruct
KeepSayingNo 2021-04-14
  • 打赏
  • 举报
回复
我也推荐BeanCopier,可以针对不同类型的对象,只要里面的属性名相同就会复制,如果你在转换过程中有其它的变化,可以自定义convert方法
  • 打赏
  • 举报
回复
fastjson 很方便

   public static void main(String[] args) {
        A a= new A();
        a.age=5;

        B b = JSON.parseObject(JSON.toJSONString(a), B.class);
        System.out.println(b.age);
        C c = JSON.parseObject(JSON.toJSONString(a), C.class);
        System.out.println(c.age);

    }

    @Data
    static class A{
        int age;
    }
    @Data
    static class B{
        Long age;
    }
    @Data
    static class C{
        BigDecimal age;
    }

结果: 5 5
小可怡情 2021-04-13
  • 打赏
  • 举报
回复
这里方法写的不全,没有处理属性有多有少的情况,如果属性名对不上会报错的
lin351550660 2021-03-28
  • 打赏
  • 举报
回复
【源码免费下载链接】:https://renmaiwang.cn/s/hqbxb JavaBeanUtils.copyProperties()方法详解 JavaBeanUtils.copyProperties()是一个功能强大的工具,其主要作用是将一个JavaBean的属性高效地复制到另一个JavaBean中。在Java编程实践中,我们经常需要处理不同对象之间属性转移问题,在Struts框架中尤其常见。传统的实现方式通常依赖于逐个赋值操作,这种方法虽然简单但效率较低且代码冗长。幸运的是,JavaBeanUtils为此提供了更高效的解决方案。 该方法的核心在于将源对象的全部属性一次性复制到目标对象,并且确保数据类型的正确转换。具体而言,在使用此方法时,开发者需要关注以下几点:首先,必须明确区分源和目标对象;其次,两个对象应具有完全相同的属性名称;最后,类型转换步骤至关重要。 一个典型的示例如下: ```java // 创建新的用户实体实例 User user = new User(); // 将ActionForm的属性高效复制至新用户实例中 BeanUtils.copyProperties(user, form); ``` 在这个代码片段中,我们成功地将ActionForm对象的所有属性复制到了一个新的User对象上。这种实现方式不仅简化了代码结构,还显著提升了程序运行效率。 需要注意的是,在某些特殊情况下(如目标对象属性名称与源对象不一致时),该方法会自动忽略这些差异,并仅执行有效赋值操作。此外,与其他类似的方法相比,JavaBeanUtils.copyProperties()的一个显著优点是支持类型转换功能。这种特性使得它特别适合在需要处理不同数据类型的场景中使用。 综上所述,JavaBeanUtils.copyProperties()是一个值得深入学习和广泛应用的

67,541

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧