是否可以使用Commons Bean Utils自动实例化嵌套属性?

Alf*_*rio 6 java reflection apache-commons-beanutils

我正在使用Apache Commons Bean Utils的PropertyUtils.setProperty(object,name,value)方法:

给这些课程:

public class A {
    B b;
}

public class B {
    C c;
}

public class C {
}
Run Code Online (Sandbox Code Playgroud)

还有这个:

A a = new A();
C c = new C();
PropertyUtils.setProperty(a, "b.c", c); //exception
Run Code Online (Sandbox Code Playgroud)

如果我尝试得到: org.apache.commons.beanutils.NestedNullException:bean类'class A ' 上'bc'的空属性值

是否有可能告诉PropertyUtils,如果嵌套属性具有空值,尝试在尝试深入之前实例化它(默认构造函数)?

还有其他方法吗?

谢谢

Alf*_*rio 9

我解决了这个问题:

private void instantiateNestedProperties(Object obj, String fieldName) {
    try {
        String[] fieldNames = fieldName.split("\\.");
        if (fieldNames.length > 1) {
            StringBuffer nestedProperty = new StringBuffer();
            for (int i = 0; i < fieldNames.length - 1; i++) {
                String fn = fieldNames[i];
                if (i != 0) {
                    nestedProperty.append(".");
                }
                nestedProperty.append(fn);

                Object value = PropertyUtils.getProperty(obj, nestedProperty.toString());

                if (value == null) {
                    PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(obj, nestedProperty.toString());
                    Class<?> propertyType = propertyDescriptor.getPropertyType();
                    Object newInstance = propertyType.newInstance();
                    PropertyUtils.setProperty(obj, nestedProperty.toString(), newInstance);
                }
            }
        }
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
        throw new RuntimeException(e);
    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    } catch (InstantiationException e) {
        throw new RuntimeException(e);
    }
}
Run Code Online (Sandbox Code Playgroud)


Noc*_*que 6

我知道问题是关于apache commons PropertyUtils.setProperty但是Spring表达式语言"SpEL "中有非常类似的功能, 它可以完全满足您的需求.更好的是它也处理列表和数组.上面的doc链接适用于spring 4.x,但下面的代码适用于我在春季3.2.9.

    StockOrder stockOrder = new StockOrder(); // Your root class here

    SpelParserConfiguration config = new SpelParserConfiguration(true,true);   // auto create objects if null
    ExpressionParser parser = new SpelExpressionParser(config);
    StandardEvaluationContext modelContext = new StandardEvaluationContext(stockOrder);

    parser.parseExpression("techId").setValue(modelContext, "XXXYYY1");
    parser.parseExpression("orderLines[0].partNumber").setValue(modelContext, "65498");
    parser.parseExpression("orderLines[0].inventories[0].serialNumber").setValue(modelContext, "54686513216");

    System.out.println(ReflectionToStringBuilder.toString(stockOrder));
Run Code Online (Sandbox Code Playgroud)