From a293fd55101b6720708a392942b1254a5cb64c4b Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 8 Nov 2022 20:20:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20BeanUtil#copyProperties=20?= =?UTF-8?q?=E6=BA=90=E5=AF=B9=E8=B1=A1=E4=B8=8E=E7=9B=AE=E6=A0=87=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E9=83=BD=E6=98=AF=20Map=20=E6=97=B6=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E5=B1=9E=E6=80=A7=E6=97=A0=E6=95=88=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../core/bean/copier/BeanToBeanCopier.java | 5 ++++ .../core/bean/copier/BeanToMapCopier.java | 5 ++++ .../hutool/core/bean/copier/CopyOptions.java | 27 ++++++------------- .../core/bean/copier/MapToBeanCopier.java | 5 ++++ .../core/bean/copier/MapToMapCopier.java | 11 ++++---- .../copier/ValueProviderToBeanCopier.java | 5 ++++ .../cn/hutool/core/bean/Issue2697Test.java | 9 ++++--- 8 files changed, 40 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb3fef749..65814234b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ * 【core 】 修复StrUtil.subWithLength负数问题(issue#I5YN49@Gitee) * 【core 】 修复DefaultTrustManager空指针问题(issue#2716@Github) * 【core 】 修复时间轮添加任务线程安全问题(pr#2712@Github) +* 【core 】 修复 BeanUtil#copyProperties 源对象与目标对象都是 Map 时设置忽略属性无效问题(pr#2698@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.9 (2022-10-22) diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToBeanCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToBeanCopier.java index e91c1914f..9c46eae43 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToBeanCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToBeanCopier.java @@ -59,6 +59,11 @@ public class BeanToBeanCopier extends AbsCopier { return; } + // 忽略不需要拷贝的 key, + if (false == copyOptions.testKeyFilter(sFieldName)) { + return; + } + // 检查目标字段可写性 final PropDesc tDesc = targetPropDescMap.get(sFieldName); if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) { diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToMapCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToMapCopier.java index 441d40a28..8ce4617ad 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToMapCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanToMapCopier.java @@ -57,6 +57,11 @@ public class BeanToMapCopier extends AbsCopier { return; } + // 忽略不需要拷贝的 key, + if (false == copyOptions.testKeyFilter(sFieldName)) { + return; + } + // 检查源对象属性是否过滤属性 Object sValue = sDesc.getValue(this.source); if (false == copyOptions.testPropertyFilter(sDesc.getField(), sValue)) { diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/CopyOptions.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/CopyOptions.java index d904c13d8..8ec09389f 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/CopyOptions.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/CopyOptions.java @@ -1,5 +1,6 @@ package cn.hutool.core.bean.copier; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.TypeConverter; import cn.hutool.core.lang.Editor; @@ -12,8 +13,6 @@ import cn.hutool.core.util.ReflectUtil; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.BiFunction; @@ -74,7 +73,7 @@ public class CopyOptions implements Serializable { /** * 源对象和目标对象都是 {@code Map} 时, 需要忽略的源对象 {@code Map} key */ - private Set ignoreKeySet; + private Set ignoreKeySet; /** * 自定义类型转换器,默认使用全局万能转换器转换 @@ -188,8 +187,8 @@ public class CopyOptions implements Serializable { * @return CopyOptions */ public CopyOptions setIgnoreProperties(String... ignoreProperties) { - this.setIgnoreKeySet(ignoreProperties); - return setPropertiesFilter((field, o) -> false == ArrayUtil.contains(ignoreProperties, field.getName())); + this.ignoreKeySet = CollUtil.newHashSet(ignoreProperties); + return this; } /** @@ -203,8 +202,8 @@ public class CopyOptions implements Serializable { */ @SuppressWarnings("unchecked") public CopyOptions setIgnoreProperties(Func1... funcs) { - final Set ignoreProperties = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName); - return setPropertiesFilter((field, o) -> false == ignoreProperties.contains(field.getName())); + this.ignoreKeySet = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName); + return this; } /** @@ -228,16 +227,6 @@ public class CopyOptions implements Serializable { return setIgnoreError(true); } - /** - * 设置忽略源 {@link Map} key set - * @param ignoreProperties 忽略的key - * @return CopyOptions - */ - public CopyOptions setIgnoreKeySet(String... ignoreProperties) { - this.ignoreKeySet = new HashSet<>(Arrays.asList(ignoreProperties)); - return this; - } - /** * 设置是否忽略字段的大小写 * @@ -388,7 +377,7 @@ public class CopyOptions implements Serializable { * @param key {@link Map} key * @return 是否保留 */ - protected boolean testMapKeyFilter(Object key) { - return this.ignoreKeySet.contains(key); + protected boolean testKeyFilter(Object key) { + return CollUtil.isEmpty(this.ignoreKeySet) || false == this.ignoreKeySet.contains(key); } } diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToBeanCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToBeanCopier.java index df9bdbf4b..aba1bc571 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToBeanCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToBeanCopier.java @@ -67,6 +67,11 @@ public class MapToBeanCopier extends AbsCopier, T> { return; } + // 忽略不需要拷贝的 key, + if (false == copyOptions.testKeyFilter(sKeyStr)) { + return; + } + // 检查目标字段可写性 final PropDesc tDesc = findPropDesc(targetPropDescMap, sKeyStr); if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) { diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToMapCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToMapCopier.java index b12d49ab6..4900aee51 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToMapCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/MapToMapCopier.java @@ -48,18 +48,17 @@ public class MapToMapCopier extends AbsCopier { return; } + // 忽略不需要拷贝的 key, + if (false == copyOptions.testKeyFilter(sKeyStr)) { + return; + } + final Object targetValue = target.get(sKeyStr); // 非覆盖模式下,如果目标值存在,则跳过 if (false == copyOptions.override && null != targetValue) { return; } - // 忽略不需要拷贝的 key, - if (true == copyOptions.testMapKeyFilter(sKey)) { - return; - } - - // 获取目标值真实类型并转换源值 final Type[] typeArguments = TypeUtil.getTypeArguments(this.targetType); if (null != typeArguments) { diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProviderToBeanCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProviderToBeanCopier.java index 35230db3c..cef5ccf0c 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProviderToBeanCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/ValueProviderToBeanCopier.java @@ -60,6 +60,11 @@ public class ValueProviderToBeanCopier extends AbsCopier mapA = new HashMap<>(16); + final Map mapA = new HashMap<>(16); mapA.put("12", "21"); mapA.put("121", "21"); mapA.put("122", "21"); - Map mapB = new HashMap<>(16); + final Map mapB = new HashMap<>(16); BeanUtil.copyProperties(mapA, mapB, "12"); - System.out.println(mapB); + + Assert.assertEquals(2, mapB.size()); + Assert.assertFalse(mapB.containsKey("12")); } }