例如对象VisitOrder,其中有成员变量houseInfo,类型是HouseInfo,HouseInfo中有成员变量houseOwner,houseOwner类型是Customer
可以通过"houseInfo.houseOwner.id"来递归设置VisitOrder
通过如下语句可以递归设置VisitOrder对象的成员变量
/***
* 18/2/12
*/
@Test
public final void test_setObjectValue() {
Map<String, Object> param = new HashMap<>();
param.put("orderNo", "INS20180212125352285XPI749");
param.put("houseInfo.id", 106);
param.put("houseInfo.houseOwner.id",255);
VisitOrder visitOrder = new VisitOrder();
ReflectHWUtils.setObjectValue(visitOrder, param);//利用反射批量设置对象的成员变量值
System.out.println("houseInfo.houseOwner.id :" +visitOrder.getHouseInfo().getHouseOwner().getId());
}
核心方法
setObjectValue
如下:
/***
* 利用反射设置对象的属性值. 注意:属性可以没有setter 方法.
*
* @param obj
* @param params
* @throws SecurityException
*/
public static void setObjectValue(Object obj, Map<String, ?> params) {
if (ValueWidget.isNullOrEmpty(obj)) {
return;
}
if (ValueWidget.isNullOrEmpty(params)) {
return;
}
Class<?> clazz = obj.getClass();
for (Iterator it = params.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, ?> entry = (Map.Entry<String, ?>) it
.next();
String key = entry.getKey();
Object propertyValue = entry.getValue();
if (ValueWidget.isNullOrEmpty(propertyValue)) {
continue;
}
if (key.contains(".")) {
setPropValueReser(obj, key, propertyValue);
} else {
Field name = getSpecifiedField(clazz, key);
if (name != null) {
setAccessibleAndVal(obj, name, propertyValue);
}
}
}
}
/***
* 成员变量如果包含英文句点,则表示设置成员变量对象中属性,支持多级,例如"houseInfo.houseOwner.id"
* @param obj
* @param key : 成员变量名称,例如:"username","agent.id"
* @param propertyValue
*/
public static void setPropValueReser(Object obj, String key, Object propertyValue) {
if (key.contains(".")) {
String[] columns = key.split("\\.", 2);
Field name = getSpecifiedField(obj.getClass(), columns[0]);
Object val1 = getObjectValue(obj, name);
if (null == val1) {
val1 = ReflectHWUtils.createEmptyObj(name.getType());
setAccessibleAndVal(obj, name, val1);
}
setPropValueReser(val1, columns[1], propertyValue);
} else {
setAccessibleAndVal(obj, getSpecifiedField(obj.getClass(), key), propertyValue);
}
}
public static void setAccessibleAndVal(Object obj, Field f, Object str) {
f.setAccessible(true);
try {
f.set(obj, str);
} catch (IllegalAccessException e) {
e.printStackTrace();
logger.error("Field.set(obj, str) error", e);
throw new LogicBusinessException(e.getMessage());
}
}
/*** * Get Specified Field * * @param clazz * @param fieldName * @return */ public static Field getSpecifiedField(Class<?> clazz, String fieldName) { if (ValueWidget.isNullOrEmpty(clazz) || ValueWidget.isNullOrEmpty(fieldName)) { return null; } Field f = null; try { f = clazz.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { Class superClass2 = clazz.getSuperclass(); if (superClass2.getName().equals(Object.class.getName())) { return null; } return getSpecifiedField(superClass2/* * may be null if it is * Object . */, fieldName); // e.printStackTrace(); } return f; }
说明:反射确认会影响性能,但是有时候很方便
参考:https://github.com/liuyu520/io0007