版权声明:本文为博主原创文章,转载请注明作者与出处,http://blog.csdn.net/lixingtao0520 https://blog.csdn.net/lixingtao0520/article/details/77149079
在工作中遇到这样一个问题: 在操作人修改单据时,需要记录此次修改的内容。此问题,最简单的方法就是对修改前和修改后的对象属性一一比较,记录修改内容。如果此单据有几十个属性时,一一比较的方法较繁琐。此时,我们用反射的方法来解决。
package com.xtli.controller.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import org.springframework.util.StringUtils;
public class ReflectUtils {
/**
* Description: 获取修改内容
*/
public static String packageModifyContent(Object source, Object target) {
StringBuffer modifyContent = new StringBuffer();
if(null == source || null == target) {
return "";
}
//取出source类
Class<?> sourceClass = source.getClass();
Field[] sourceFields = sourceClass.getDeclaredFields();
for(Field srcField : sourceFields) {
String srcName = srcField.getName();
//获取srcField值
String srcValue = getFieldValue(source, srcName) == null ? "" : getFieldValue(source, srcName).toString();
//获取对应的targetField值
String targetValue = getFieldValue(target, srcName) == null ? "" : getFieldValue(target, srcName).toString();
if(StringUtils.isEmpty(srcValue) && StringUtils.isEmpty(targetValue)) {
continue;
}
if(!srcValue.equals(targetValue)) {
modifyContent.append(srcName + "由‘" + targetValue + "’修改为‘" + srcValue + "’;");
}
}
return modifyContent.toString();
}
/**
* Description: 获取Obj对象的fieldName属性的值
*/
private static Object getFieldValue(Object obj, String fieldName) {
Object fieldValue = null;
if(null == obj) {
return null;
}
Method[] methods = obj.getClass().getDeclaredMethods();
for (Method method : methods) {
String methodName = method.getName();
if(!methodName.startsWith("get")) {
continue;
}
if(methodName.startsWith("get") && methodName.substring(3).toUpperCase().equals(fieldName.toUpperCase())) {
try {
fieldValue = method.invoke(obj, new Object[] {});
} catch (Exception e) {
System.out.println("取值出错,方法名 " + methodName);
continue;
}
}
}
return fieldValue;
}
}
此方法可以记录下source对象和target对象全部属性的不同,解决问题。
以上方法记录的是两个对象的全部属性,如果我们只想记录部分关键属性,怎么办?只需要增加一个Map参数即可,此Map参数是关键属性的映射集合。(用map而不是set,是因为可以给属性映射一个别名)。改进后的packageModifyContent方法如下:
/**
* Description: 获取修改内容
*/
public static String packageModifyContent(Object source, Object target, Map<String,String> comparedProperties) {
StringBuffer modifyContent = new StringBuffer();
if(null == source || null == target) {
return "";
}
//取出source类
Class<?> sourceClass = source.getClass();
Field[] sourceFields = sourceClass.getDeclaredFields();
for(Field srcField : sourceFields) {
String srcName = srcField.getName();
//获取此属性值。条件: 1 比较所有属性; 2 比较的属性在比较集合中
if(null == comparedProperties || (null != comparedProperties && comparedProperties.containsKey(srcName))) {
//获取srcField值
String srcValue = getFieldValue(source, srcName) == null ? "" : getFieldValue(source, srcName).toString();
//获取对应的targetField值
String targetValue = getFieldValue(target, srcName) == null ? "" : getFieldValue(target, srcName).toString();
if(StringUtils.isEmpty(srcValue) && StringUtils.isEmpty(targetValue)) {
continue;
}
if(!srcValue.equals(targetValue)) {
modifyContent.append(comparedProperties.get(srcName) + "由‘" + targetValue + "’修改为‘" + srcValue + "’;");
}
}
}
return modifyContent.toString();
}