反射应用:比较两个对象属性的不同

版权声明:本文为博主原创文章,转载请注明作者与出处,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();
	}



猜你喜欢

转载自blog.csdn.net/lixingtao0520/article/details/77149079
今日推荐