有没有办法使用BeanUtils.copyProperties将Set映射到List?

时间:2014-10-17 09:36:46

标签: java spring mapping

我正在使用BeanUtils.copyProperties转换两个bean。

BeanUtils.copyProperties(organization, dtoOrganization);

我希望在一个bean中有List,在另一个bean中有Set

第一个豆:

public class Form {

  private Set<Organization> organization;

}

第二个豆子:

public final class DTOForm {

  private List<DTOOrganization> organization;

}

结果是如下所述的例外情况: argument type mismatch by Using BeanUtils.copyProperties

是否可以自定义BeanUtils.copyProperties来实现它?

2 个答案:

答案 0 :(得分:1)

从一种类型的集合转换为另一种类型的列表是一个很大的延伸。

虽然您可以通过创建自定义JavaBeans PropertyEditors来实现它,但我更喜欢使用像Dozer这样的Mapper框架。

答案 1 :(得分:1)

您可以使用自定义转换器解决此问题。主要想法是使用ConvertUtils.register(Converter converter, Class<?> clazz)Set注册新的转换器。实现自定义的set-to-list转换器的convert(Class<T> type, Object value)方法不是问题。

以下是您的问题的简单示例:

ListEntity,具有List属性(据我所知,不要忽略setter和getter,它们的存在是强制性的):

public class ListEntity {
    private List<Integer> col = new ArrayList<>();

    public List<Integer> getCol() {
        return col;
    }

    public void setCol(List<Integer> col) {
        this.col = col;
    }
}

SetEntity,具有Set属性:

public class SetEntity {
    private Set<Integer> col = new HashSet<>();

    public Set<Integer> getCol() {
        return col;
    }

    public void setCol(Set<Integer> col) {
        this.col = col;
    }
}

要在工作中使用的简单测试类:

public class Test {
    public static void main(String... args) throws InvocationTargetException, IllegalAccessException {
        SetEntity se = new SetEntity();
        se.getCol().add(1);
        se.getCol().add(2);
        ListEntity le = new ListEntity();
        ConvertUtils.register(new Converter() {
            @Override
            public <T> T convert(Class<T> tClass, Object o) {
                List list = new ArrayList<>();
                Iterator it = ((Set)o).iterator();
                while (it.hasNext()) {
                    list.add(it.next());
                }
                return (T)list;
            }
        }, List.class);
        BeanUtils.copyProperties(le, se);
        System.out.println(se.getCol().toString());
        System.out.println(le.getCol().toString());
    }
}

此代码片段的主要思想是:我们为所有目标类List属性注册转换器,它会尝试将某个对象o转换为List。假设o是一个集合,我们迭代它然后返回新创建的列表。

因此,le将包含12值。如果您不再需要此转换器,则可以使用ConvertUtils.deregister()取消注册。