需求:
对比两个版本的详情,对出现修改的地方进行标注表示此处有修改。
PART 1:
改良自org.springframework.beans.BeanUtils下的copyProperties方法
public static List<String> checkDiffFiled(Object source, Object target){
List<String> result = new ArrayList<>();
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> actualEditable = target.getClass();
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
for (PropertyDescriptor targetPd : targetPds) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readTarget = targetPd.getReadMethod();
Method readSource = sourcePd.getReadMethod();
if (readTarget != null && readSource != null) {
ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readSource);
ResolvableType targetResolvableType = ResolvableType.forMethodReturnType(readTarget);
boolean isAssignable =
(sourceResolvableType.hasUnresolvableGenerics() || targetResolvableType.hasUnresolvableGenerics() ?
ClassUtils.isAssignable(readTarget.getReturnType(), readSource.getReturnType()) : targetResolvableType.isAssignableFrom(sourceResolvableType));
if (isAssignable) {
try {
if (!Modifier.isPublic(readSource.getDeclaringClass().getModifiers())) {
readSource.setAccessible(true);
}
Object value1 = readSource.invoke(source);
if (!Modifier.isPublic(readTarget.getDeclaringClass().getModifiers())) {
readTarget.setAccessible(true);
}
Object value2 = readTarget.invoke(target);
if (!Objects.equals(value1,value2))
result.add(targetPd.getName());
}
catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}
return result;
}
PART 2:
在上一版结束后,拿去前端对接口开发了,随后前端同学提出对象下的子对象的值不一致无法识别到。思考了一下咱递归不就行了,递归条件是如果当前字段存在多个字段值就往下深入,如果只有一个字段值为啥要放在对象里呢! 递归的坑点肯定比较多,所以排除了一些字段的校验,否则会无限套娃。
public class CheckBeanUtil {
public static List<String> checkDiffFiled(Object source, Object target, @Nullable String pPath){
List<String> result = new ArrayList<>();
if (!StringUtils.hasText(pPath))
pPath = "";
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> actualEditable = target.getClass();
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
for (PropertyDescriptor targetPd : targetPds) {
if (targetPd.getName().equals("class"))
continue;
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readTarget = targetPd.getReadMethod();
Method readSource = sourcePd.getReadMethod();
if (readTarget != null && readSource != null) {
ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readSource);
ResolvableType targetResolvableType = ResolvableType.forMethodReturnType(readTarget);
boolean isAssignable =
(sourceResolvableType.hasUnresolvableGenerics() || targetResolvableType.hasUnresolvableGenerics() ?
ClassUtils.isAssignable(readTarget.getReturnType(), readSource.getReturnType()) : targetResolvableType.isAssignableFrom(sourceResolvableType));
if (isAssignable) {
try {
if (!Modifier.isPublic(readSource.getDeclaringClass().getModifiers())) {
readSource.setAccessible(true);
}
Object value1 = readSource.invoke(source);
if (!Modifier.isPublic(readTarget.getDeclaringClass().getModifiers())) {
readTarget.setAccessible(true);
}
Object value2 = readTarget.invoke(target);
if (Objects.nonNull(value1) && Objects.nonNull(value2) && checkType(value1) && getPropertyDescriptors(value1.getClass()).length > 1){
result.addAll(checkDiffFiled(value1,value2,pPath + targetPd.getName() + "."));
}else if (!Objects.equals(value1,value2))
result.add(pPath + targetPd.getName());
}
catch (Throwable ex) {
throw new FatalBeanException(
"Could not compaire property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}
return result;
}
private static boolean checkType(Object obj){
if (obj instanceof String
|| obj instanceof LocalDateTime
|| obj instanceof JSONArray
)
return false;
return true;
}
}
Part3:
前端:你这JSON格式的字符串没有细化到每一行啊,我这干不了,,,,是不可能的,大哥你先放下刀好好说话,,,啊,,
啊,世界清静了
|