我正在使用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).
如果其中一个中间属性是null
,BeanUtils的行为就是什么都不做。例如,在我的情况下,home
的{{1}}属性为family
,没有任何反应。如果我做
null
然后family = new Family();
将为null,我也必须初始化它。显然,我的真实用例更复杂,有许多动态属性(以及索引的属性)。
有没有办法告诉BeanUtils实例化中间成员?我知道通常这是不可能的(因为可能不知道属性的具体类型)。但在我的情况下,所有属性都有具体的类型,并且是正确的bean(使用公共的无参数构造函数)。所以有可能。
我想确保在推出自己的解决方案之前还没有现成的解决方案(使用BeanUtils或其他方法)。
答案 0 :(得分: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);
}
}
// [...]
}