java - 使用 BeanUtils 或类似工具将非空属性从一个对象复制到另一个对象

标签 java spring javabeans

我的目标是将一个对象的字段复制到另一个对象中,但仅限那些不为空的字段。我不想明确分配它。更通用的解决方案将非常有用且更易于维护,即在 REST API 中实现 PATCH,您只允许提供特定字段。

我看到了这个类似的帖子,我正在尝试实现这里的一些想法:Helper in order to copy non null properties from object to another ? (Java)

但是对象在程序执行后没有任何改变。

所以这是我创建的示例类,例如:

class Person {
    String name;
    int age;
    Pet friend;

    public Person() {
    }

    public Person(String name, int age, Pet friend) {
        this.name = name;
        this.age = age;
        this.friend = friend;
    }

    // getters and setters here
}

class Pet {
    String name;
    int age;

    public Pet(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // getters and setters here
}

这是我重写的 copyProperty 方法:

import org.apache.commons.beanutils.BeanUtilsBean;
import java.lang.reflect.InvocationTargetException;

public class MyBeansUtil extends BeanUtilsBean {

@Override
public void copyProperty(Object dest, String name, Object value)
        throws IllegalAccessException, InvocationTargetException {
    if(value == null) return;
    super.copyProperty(dest, name, value);
}
}

...这是我尝试在一些示例中对其进行测试的地方:

public class SandBox {
    public static void main(String[] args) {
        Person db = new Person("John", 36, new Pet("Lucy", 3));
        Person db2 = new Person("John", 36, new Pet("Lucy", 2));
        Person db3 = new Person("John", 36, new Pet("Lucy", 4));

        Person in = new Person();
        in.age = 17;
        in.name = "Paul";
        in.friend = new Pet(null, 35);

        Person in2 = new Person();
        in2.name = "Damian";

        Person in3 = new Person();
        in3.friend = new Pet("Lup", 25);

        try {
            BeanUtilsBean notNull  =new MyBeansUtil();
            notNull.copyProperties(db, in);
            notNull.copyProperties(db2, in2);
            notNull.copyProperties(db3, in3);

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

不幸的是,原始对象 db、db1、db2 保持原样。我在这里做错了什么吗?

最佳答案

我最终使用了 Spring BeanUtils 库。这是我的工作方法:

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.lang.reflect.Field;
import java.util.Collection;

public class MyBeansUtil<T> {
    public T copyNonNullProperties(T target, T in) {
        if (in == null || target == null || target.getClass() != in.getClass()) return null;

        final BeanWrapper src = new BeanWrapperImpl(in);
        final BeanWrapper trg = new BeanWrapperImpl(target);

        for (final Field property : target.getClass().getDeclaredFields()) {
            Object providedObject = src.getPropertyValue(property.getName());
            if (providedObject != null && !(providedObject instanceof Collection<?>)) {
                trg.setPropertyValue(
                        property.getName(),
                        providedObject);
            }
        }
        return target;
    }
}

它工作正常,但请注意它忽略了作为集合的字段。这是故意的,我分别处理它们。

关于java - 使用 BeanUtils 或类似工具将非空属性从一个对象复制到另一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41125384/

相关文章:

java - 在java中的类之间共享更新数据的最佳方式

spring - Keycloak:作为 docker 服务运行时无效的 token 颁发者

java - 无法使用 <jsp :useBean>: "Bean cannot be resolved to a type"

java - 将 Java Bean 扁平化为 map

java - 如何在jsp中使用bean类向数据库中插入值?

java - 防止下拉列表选项在 SWT 中的 Windows 上滚动

java - 在 Servlet 端使用 excel 表生成内存中的 zip 文件

java - 未找到 StringUtils 类

java - 如何使用 Spring Kafka 实现有状态的消息监听器?

java - spring中如何根据profile调用一个bean的不同实现