3

我正在使用 BeanUtils.setProperty 在 bean 上设置深层属性。

Home home = new Home() ;
String path = "home.family.father.age";
Integer value = 40;

BeanUtils.setProperty(home, path, value);
// Does the same as home.getHome().getFamily().getFather().setAge(value);
// But stops on null (instead of throwing an NPE).

如果中间属性之一是 ,则 BeanUtils 的行为是什么都不做null。因此,例如在我的情况下,home' 的family属性是null,并且没有任何反应。如果我做

family = new Family();

然后father将为空,我也必须初始化它。显然,我的真实用例更复杂,具有许多动态属性(以及索引属性)。

有没有办法告诉 BeanUtils 实例化中间成员?我知道通常这是不可能的(因为可能不知道属性的具体类型)。但在我的情况下,所有属性都有具体的类型并且是正确的 bean(具有公共的无参数构造函数)。所以这是可能的。

在推出自己的解决方案之前,我想确保没有现有的解决方案(使用 BeanUtils 或其他东西)。

4

1 回答 1

1

我自己滚动。它只支持简单的属性,但我想添加对嵌套/映射属性的支持不会太难。

如果有人需要同样的东西,这里有一个要点: https ://gist.github.com/ThomasGirard/7115693

这是最重要的部分:

/** Mostly copy-pasted from {@link PropertyUtilsBean.setProperty}. */
public void initProperty(Object bean, String path) throws SecurityException, NoSuchMethodException,
        IllegalAccessException, InvocationTargetException {

    // [...]

    // If the component is null, initialize it
    if (nestedBean == null) {

        // There has to be a method get* matching this path segment
        String methodName = "get" + StringUtils.capitalize(next);
        Method m = bean.getClass().getMethod(methodName);

        // The return type of this method is the object type we need to init.
        Class<?> propType = m.getReturnType();
        try {
            // Since it's a bean it must have a no-arg public constructor
            Object newInst = propType.newInstance();
            PropertyUtils.setProperty(bean, next, newInst);
            // Now we have something instead of null
            nestedBean = newInst;
        } catch (Exception e) {
            throw new NestedNullException("Could not init property value for '" + path + "' on bean class '"
                    + bean.getClass() + "'. Class: " + propType);
        }
    }

    // [...]

}
于 2013-10-23T09:54:35.657 回答