From d8de98cbfc692a9b29644569cf8e77adf35d3860 Mon Sep 17 00:00:00 2001 From: kfyty725 Date: Fri, 19 Mar 2021 14:19:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=B1=9E=E6=80=A7=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=E9=80=89=E9=A1=B9=E6=B7=BB=E5=8A=A0=E5=B1=9E=E6=80=A7=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/bean/copier/BeanCopier.java | 6 ++++++ .../hutool/core/bean/copier/CopyOptions.java | 19 +++++++++++++++++++ .../cn/hutool/core/bean/BeanUtilTest.java | 13 +++++++++++++ 3 files changed, 38 insertions(+) diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java index 7d54e7a9c..f9ef1239c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java @@ -188,6 +188,9 @@ public class BeanCopier implements Copier, Serializable { 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) { // 当允许跳过空时,跳过 //值不能为bean本身,防止循环引用,此类也跳过 @@ -245,6 +248,9 @@ public class BeanCopier implements Copier, Serializable { // 获取属性值 Object value = valueProvider.value(providerKey, fieldType); + if(!copyOptions.propertiesFilter.test(prop.getField(), value)) { + return; + } if ((null == value && copyOptions.ignoreNullValue) || bean == value) { // 当允许跳过空时,跳过 // 值不能为bean本身,防止循环引用 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 921b46a10..fdc759aba 100644 --- 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 @@ -5,7 +5,9 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import java.io.Serializable; +import java.lang.reflect.Field; import java.util.Map; +import java.util.function.BiPredicate; /** * 属性拷贝选项
@@ -27,6 +29,10 @@ public class CopyOptions implements Serializable { * 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null */ protected boolean ignoreNullValue; + /** + * 属性过滤器,断言通过的属性才会被复制 + */ + protected BiPredicate propertiesFilter; /** * 忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值 */ @@ -81,6 +87,7 @@ public class CopyOptions implements Serializable { * 构造拷贝选项 */ public CopyOptions() { + this.propertiesFilter = (f, v) -> true; } /** @@ -91,6 +98,7 @@ public class CopyOptions implements Serializable { * @param ignoreProperties 忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值 */ public CopyOptions(Class editable, boolean ignoreNullValue, String... ignoreProperties) { + this(); this.editable = editable; this.ignoreNullValue = ignoreNullValue; this.ignoreProperties = ignoreProperties; @@ -128,6 +136,17 @@ public class CopyOptions implements Serializable { return setIgnoreNullValue(true); } + /** + * 属性过滤器,断言通过的属性才会被复制 + * + * @param propertiesFilter 属性过滤器 + * @return CopyOptions + */ + public CopyOptions setPropertiesFilter(BiPredicate propertiesFilter) { + this.propertiesFilter = propertiesFilter; + return this; + } + /** * 设置忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值 * diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java index a54fea44e..51626279f 100644 --- a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java @@ -6,6 +6,7 @@ import cn.hutool.core.bean.copier.ValueProvider; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; import lombok.Data; import lombok.Getter; import lombok.Setter; @@ -461,6 +462,18 @@ public class BeanUtilTest { 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 public static class Food { @Alias("bookId")