!281 属性拷贝选项添加属性过滤器

Merge pull request !281 from kfyty/v5-dev
This commit is contained in:
Looly 2021-03-19 16:10:49 +08:00 committed by Gitee
commit 3990516a31
3 changed files with 38 additions and 0 deletions

View File

@ -188,6 +188,9 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
throw new BeanException(e, "Get value of [{}] error!", prop.getFieldName()); throw new BeanException(e, "Get value of [{}] error!", prop.getFieldName());
} }
} }
if(!copyOptions.propertiesFilter.test(prop.getField(), value)) {
return;
}
if ((null == value && copyOptions.ignoreNullValue) || bean == value) { if ((null == value && copyOptions.ignoreNullValue) || bean == value) {
// 当允许跳过空时跳过 // 当允许跳过空时跳过
//值不能为bean本身防止循环引用此类也跳过 //值不能为bean本身防止循环引用此类也跳过
@ -245,6 +248,9 @@ public class BeanCopier<T> implements Copier<T>, Serializable {
// 获取属性值 // 获取属性值
Object value = valueProvider.value(providerKey, fieldType); Object value = valueProvider.value(providerKey, fieldType);
if(!copyOptions.propertiesFilter.test(prop.getField(), value)) {
return;
}
if ((null == value && copyOptions.ignoreNullValue) || bean == value) { if ((null == value && copyOptions.ignoreNullValue) || bean == value) {
// 当允许跳过空时跳过 // 当允许跳过空时跳过
// 值不能为bean本身防止循环引用 // 值不能为bean本身防止循环引用

View File

@ -5,7 +5,9 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Map; import java.util.Map;
import java.util.function.BiPredicate;
/** /**
* 属性拷贝选项<br> * 属性拷贝选项<br>
@ -27,6 +29,10 @@ public class CopyOptions implements Serializable {
* 是否忽略空值当源对象的值为null时true: 忽略而不注入此值false: 注入null * 是否忽略空值当源对象的值为null时true: 忽略而不注入此值false: 注入null
*/ */
protected boolean ignoreNullValue; protected boolean ignoreNullValue;
/**
* 属性过滤器断言通过的属性才会被复制
*/
protected BiPredicate<Field, Object> propertiesFilter;
/** /**
* 忽略的目标对象中属性列表设置一个属性列表不拷贝这些属性值 * 忽略的目标对象中属性列表设置一个属性列表不拷贝这些属性值
*/ */
@ -81,6 +87,7 @@ public class CopyOptions implements Serializable {
* 构造拷贝选项 * 构造拷贝选项
*/ */
public CopyOptions() { public CopyOptions() {
this.propertiesFilter = (f, v) -> true;
} }
/** /**
@ -91,6 +98,7 @@ public class CopyOptions implements Serializable {
* @param ignoreProperties 忽略的目标对象中属性列表设置一个属性列表不拷贝这些属性值 * @param ignoreProperties 忽略的目标对象中属性列表设置一个属性列表不拷贝这些属性值
*/ */
public CopyOptions(Class<?> editable, boolean ignoreNullValue, String... ignoreProperties) { public CopyOptions(Class<?> editable, boolean ignoreNullValue, String... ignoreProperties) {
this();
this.editable = editable; this.editable = editable;
this.ignoreNullValue = ignoreNullValue; this.ignoreNullValue = ignoreNullValue;
this.ignoreProperties = ignoreProperties; this.ignoreProperties = ignoreProperties;
@ -128,6 +136,17 @@ public class CopyOptions implements Serializable {
return setIgnoreNullValue(true); return setIgnoreNullValue(true);
} }
/**
* 属性过滤器断言通过的属性才会被复制
*
* @param propertiesFilter 属性过滤器
* @return CopyOptions
*/
public CopyOptions setPropertiesFilter(BiPredicate<Field, Object> propertiesFilter) {
this.propertiesFilter = propertiesFilter;
return this;
}
/** /**
* 设置忽略的目标对象中属性列表设置一个属性列表不拷贝这些属性值 * 设置忽略的目标对象中属性列表设置一个属性列表不拷贝这些属性值
* *

View File

@ -6,6 +6,7 @@ import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -461,6 +462,18 @@ public class BeanUtilTest {
Assert.assertNull(newFood.getCode()); Assert.assertNull(newFood.getCode());
} }
@Test
public void copyBeanPropertiesFilterTest() {
Food info = new Food();
info.setBookID("0");
info.setCode("");
Food newFood = new Food();
CopyOptions copyOptions = CopyOptions.create().setPropertiesFilter((f, v) -> !(v instanceof CharSequence) || StrUtil.isNotBlank(v.toString()));
BeanUtil.copyProperties(info, newFood, copyOptions);
Assert.assertEquals(info.getBookID(), newFood.getBookID());
Assert.assertNull(newFood.getCode());
}
@Data @Data
public static class Food { public static class Food {
@Alias("bookId") @Alias("bookId")