Is it possible to automatically create a nested property with Commons Bean Utils?

I use the PropertyUtils.setProperty (object, name, value) method of the Apache Commons Bean Utilities:

The provision of these classes:

public class A {
    B b;
}

public class B {
    C c;
}

public class C {
}

And this:

A a = new A();
C c = new C();
PropertyUtils.setProperty(a, "b.c", c); //exception

If I try, I get: org.apache.commons.beanutils.NestedNullException: Null property value for 'bc' in Bean class 'class A '

Can I tell PropertyUtils that if the attached property is null, try creating one (the default constructor) before trying to go deeper?

Any other approach?

thank

+5
source share
6 answers

, :

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);
    }
}
+8

, apache commons PropertyUtils.setProperty, , Spring "SpEL", , . , . doc spring 4.x, spring 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));
+3

:

String fn = fieldNames[i];
if (i != 0) {
        nestedProperty.append(".");
}
nestedProperty.append(fn);
Object value = PropertyUtils.getProperty(obj, nestedProperty.toString());
+2

Apache . , , , POJO, - . , .

public Object getOrCreateEmbeddedObject(Object inputObj,String[] fieldNames) throws Exception {

    Object cursor = inputObj;

    //Loop until second last index
    for (int i = 0; i < fieldNames.length - 1; i++){
        Field ff = getClassFieldFrom(cursor,fieldNames[i]);
        Object child = ff.get(cursor);
        if(null == child) {
            Class<?> cls=ff.getType();
            child = cls.newInstance();
            ff.set(cursor, child);
        }
        cursor = child;
    }

    return cursor;
}

private Field getClassFieldFrom(Object object, String fieldStr)
            throws NoSuchFieldException {
        java.lang.reflect.Field ff = object.getClass().getDeclaredField(fieldStr);
        ff.setAccessible(true);
        return ff;
}

- , .

0

:

public class A {
    B b = new B();
}

public class B {
    C c = new C();
}

public class C {
}

, .

0

" ..." - .

-1

All Articles