mirror of
https://gitee.com/dromara/hutool.git
synced 2025-06-28 13:34:09 +08:00
修复 BeanUtil#copyProperties 源对象与目标对象都是 Map 时设置忽略属性无效问题
This commit is contained in:
parent
4fdc443a4e
commit
a293fd5510
@ -21,6 +21,7 @@
|
|||||||
* 【core 】 修复StrUtil.subWithLength负数问题(issue#I5YN49@Gitee)
|
* 【core 】 修复StrUtil.subWithLength负数问题(issue#I5YN49@Gitee)
|
||||||
* 【core 】 修复DefaultTrustManager空指针问题(issue#2716@Github)
|
* 【core 】 修复DefaultTrustManager空指针问题(issue#2716@Github)
|
||||||
* 【core 】 修复时间轮添加任务线程安全问题(pr#2712@Github)
|
* 【core 】 修复时间轮添加任务线程安全问题(pr#2712@Github)
|
||||||
|
* 【core 】 修复 BeanUtil#copyProperties 源对象与目标对象都是 Map 时设置忽略属性无效问题(pr#2698@Github)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
# 5.8.9 (2022-10-22)
|
# 5.8.9 (2022-10-22)
|
||||||
|
@ -59,6 +59,11 @@ public class BeanToBeanCopier<S, T> extends AbsCopier<S, T> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 忽略不需要拷贝的 key,
|
||||||
|
if (false == copyOptions.testKeyFilter(sFieldName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查目标字段可写性
|
// 检查目标字段可写性
|
||||||
final PropDesc tDesc = targetPropDescMap.get(sFieldName);
|
final PropDesc tDesc = targetPropDescMap.get(sFieldName);
|
||||||
if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) {
|
if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) {
|
||||||
|
@ -57,6 +57,11 @@ public class BeanToMapCopier extends AbsCopier<Object, Map> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 忽略不需要拷贝的 key,
|
||||||
|
if (false == copyOptions.testKeyFilter(sFieldName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查源对象属性是否过滤属性
|
// 检查源对象属性是否过滤属性
|
||||||
Object sValue = sDesc.getValue(this.source);
|
Object sValue = sDesc.getValue(this.source);
|
||||||
if (false == copyOptions.testPropertyFilter(sDesc.getField(), sValue)) {
|
if (false == copyOptions.testPropertyFilter(sDesc.getField(), sValue)) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.hutool.core.bean.copier;
|
package cn.hutool.core.bean.copier;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.convert.TypeConverter;
|
import cn.hutool.core.convert.TypeConverter;
|
||||||
import cn.hutool.core.lang.Editor;
|
import cn.hutool.core.lang.Editor;
|
||||||
@ -12,8 +13,6 @@ import cn.hutool.core.util.ReflectUtil;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
@ -74,7 +73,7 @@ public class CopyOptions implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 源对象和目标对象都是 {@code Map} 时, 需要忽略的源对象 {@code Map} key
|
* 源对象和目标对象都是 {@code Map} 时, 需要忽略的源对象 {@code Map} key
|
||||||
*/
|
*/
|
||||||
private Set<Object> ignoreKeySet;
|
private Set<String> ignoreKeySet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义类型转换器,默认使用全局万能转换器转换
|
* 自定义类型转换器,默认使用全局万能转换器转换
|
||||||
@ -188,8 +187,8 @@ public class CopyOptions implements Serializable {
|
|||||||
* @return CopyOptions
|
* @return CopyOptions
|
||||||
*/
|
*/
|
||||||
public CopyOptions setIgnoreProperties(String... ignoreProperties) {
|
public CopyOptions setIgnoreProperties(String... ignoreProperties) {
|
||||||
this.setIgnoreKeySet(ignoreProperties);
|
this.ignoreKeySet = CollUtil.newHashSet(ignoreProperties);
|
||||||
return setPropertiesFilter((field, o) -> false == ArrayUtil.contains(ignoreProperties, field.getName()));
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -203,8 +202,8 @@ public class CopyOptions implements Serializable {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <P, R> CopyOptions setIgnoreProperties(Func1<P, R>... funcs) {
|
public <P, R> CopyOptions setIgnoreProperties(Func1<P, R>... funcs) {
|
||||||
final Set<String> ignoreProperties = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName);
|
this.ignoreKeySet = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName);
|
||||||
return setPropertiesFilter((field, o) -> false == ignoreProperties.contains(field.getName()));
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,16 +227,6 @@ public class CopyOptions implements Serializable {
|
|||||||
return setIgnoreError(true);
|
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
|
* @param key {@link Map} key
|
||||||
* @return 是否保留
|
* @return 是否保留
|
||||||
*/
|
*/
|
||||||
protected boolean testMapKeyFilter(Object key) {
|
protected boolean testKeyFilter(Object key) {
|
||||||
return this.ignoreKeySet.contains(key);
|
return CollUtil.isEmpty(this.ignoreKeySet) || false == this.ignoreKeySet.contains(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,11 @@ public class MapToBeanCopier<T> extends AbsCopier<Map<?, ?>, T> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 忽略不需要拷贝的 key,
|
||||||
|
if (false == copyOptions.testKeyFilter(sKeyStr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查目标字段可写性
|
// 检查目标字段可写性
|
||||||
final PropDesc tDesc = findPropDesc(targetPropDescMap, sKeyStr);
|
final PropDesc tDesc = findPropDesc(targetPropDescMap, sKeyStr);
|
||||||
if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) {
|
if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) {
|
||||||
|
@ -48,18 +48,17 @@ public class MapToMapCopier extends AbsCopier<Map, Map> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 忽略不需要拷贝的 key,
|
||||||
|
if (false == copyOptions.testKeyFilter(sKeyStr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final Object targetValue = target.get(sKeyStr);
|
final Object targetValue = target.get(sKeyStr);
|
||||||
// 非覆盖模式下,如果目标值存在,则跳过
|
// 非覆盖模式下,如果目标值存在,则跳过
|
||||||
if (false == copyOptions.override && null != targetValue) {
|
if (false == copyOptions.override && null != targetValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 忽略不需要拷贝的 key,
|
|
||||||
if (true == copyOptions.testMapKeyFilter(sKey)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 获取目标值真实类型并转换源值
|
// 获取目标值真实类型并转换源值
|
||||||
final Type[] typeArguments = TypeUtil.getTypeArguments(this.targetType);
|
final Type[] typeArguments = TypeUtil.getTypeArguments(this.targetType);
|
||||||
if (null != typeArguments) {
|
if (null != typeArguments) {
|
||||||
|
@ -60,6 +60,11 @@ public class ValueProviderToBeanCopier<T> extends AbsCopier<ValueProvider<String
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 忽略不需要拷贝的 key,
|
||||||
|
if (false == copyOptions.testKeyFilter(tFieldName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查目标字段可写性
|
// 检查目标字段可写性
|
||||||
if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) {
|
if (null == tDesc || false == tDesc.isWritable(this.copyOptions.transientSupport)) {
|
||||||
// 字段不可写,跳过之
|
// 字段不可写,跳过之
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.hutool.core.bean;
|
package cn.hutool.core.bean;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -13,12 +14,14 @@ public class Issue2697Test {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void mapToMapTest(){
|
public void mapToMapTest(){
|
||||||
Map<String, String> mapA = new HashMap<>(16);
|
final Map<String, String> mapA = new HashMap<>(16);
|
||||||
mapA.put("12", "21");
|
mapA.put("12", "21");
|
||||||
mapA.put("121", "21");
|
mapA.put("121", "21");
|
||||||
mapA.put("122", "21");
|
mapA.put("122", "21");
|
||||||
Map<String, String> mapB = new HashMap<>(16);
|
final Map<String, String> mapB = new HashMap<>(16);
|
||||||
BeanUtil.copyProperties(mapA, mapB, "12");
|
BeanUtil.copyProperties(mapA, mapB, "12");
|
||||||
System.out.println(mapB);
|
|
||||||
|
Assert.assertEquals(2, mapB.size());
|
||||||
|
Assert.assertFalse(mapB.containsKey("12"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user