This commit is contained in:
Looly 2024-09-18 15:18:12 +08:00
parent 8ec9e2e55d
commit 71019b6935
7 changed files with 35 additions and 34 deletions

View File

@ -137,7 +137,7 @@ public class DynaBean implements Cloneable, Serializable {
return null; return null;
//throw new BeanException("No public field or get method for {}", fieldName); //throw new BeanException("No public field or get method for {}", fieldName);
} }
return (T) prop.getValue(bean); return (T) prop.getValue(bean, false);
} }
} }

View File

@ -158,7 +158,7 @@ public class PropDesc {
} }
/** /**
* 检查属性是否可读即是否可以通过{@link #getValue(Object)}获取到值 * 检查属性是否可读即是否可以通过{@link #getValue(Object, boolean)}获取到值
* *
* @param checkTransient 是否检查Transient关键字或注解 * @param checkTransient 是否检查Transient关键字或注解
* @return 是否可读 * @return 是否可读
@ -194,14 +194,21 @@ public class PropDesc {
* 此方法不检查任何注解使用前需调用 {@link #isReadable(boolean)} 检查是否可读 * 此方法不检查任何注解使用前需调用 {@link #isReadable(boolean)} 检查是否可读
* *
* @param bean Bean对象 * @param bean Bean对象
* @param ignoreError 是否忽略读取错误
* @return 字段值 * @return 字段值
* @since 4.0.5 * @since 4.0.5
*/ */
public Object getValue(final Object bean) { public Object getValue(final Object bean, final boolean ignoreError) {
if (null != this.getter) { try{
return this.getter.invoke(bean); if (null != this.getter) {
} else if (null != this.fieldInvoker) { return this.getter.invoke(bean);
return fieldInvoker.invoke(bean); } else if (null != this.fieldInvoker) {
return fieldInvoker.invoke(bean);
}
} catch (final Exception e) {
if (!ignoreError) {
throw new BeanException(e, "Get value of [{}] error!", getFieldName());
}
} }
return null; return null;
@ -218,14 +225,7 @@ public class PropDesc {
* @since 5.4.2 * @since 5.4.2
*/ */
public Object getValue(final Object bean, final Type targetType, final boolean ignoreError) { public Object getValue(final Object bean, final Type targetType, final boolean ignoreError) {
Object result = null; final Object result = getValue(bean, ignoreError);
try {
result = getValue(bean);
} catch (final Exception e) {
if (!ignoreError) {
throw new BeanException(e, "Get value of [{}] error!", getFieldName());
}
}
if (null != result && null != targetType) { if (null != result && null != targetType) {
// 尝试将结果转换为目标类型如果转换失败返回null即跳过此属性值 // 尝试将结果转换为目标类型如果转换失败返回null即跳过此属性值
@ -237,7 +237,7 @@ public class PropDesc {
} }
/** /**
* 检查属性是否可读即是否可以通过{@link #getValue(Object)}获取到值 * 检查属性是否可读即是否可以通过{@link #getValue(Object, boolean)}获取到值
* *
* @param checkTransient 是否检查Transient关键字或注解 * @param checkTransient 是否检查Transient关键字或注解
* @return 是否可读 * @return 是否可读
@ -318,7 +318,7 @@ public class PropDesc {
// issue#I4JQ1N@Gitee // issue#I4JQ1N@Gitee
// 非覆盖模式下如果目标值存在则跳过 // 非覆盖模式下如果目标值存在则跳过
if (!override && null != getValue(bean)) { if (!override && null != getValue(bean, ignoreError)) {
return this; return this;
} }

View File

@ -54,6 +54,7 @@ public class BeanToBeanCopier<S, T> extends AbsCopier<S, T> {
@Override @Override
public T copy() { public T copy() {
final CopyOptions copyOptions = this.copyOptions;
Class<?> actualEditable = target.getClass(); Class<?> actualEditable = target.getClass();
if (null != copyOptions.editable) { if (null != copyOptions.editable) {
// 检查限制类是否为target的父类或接口 // 检查限制类是否为target的父类或接口
@ -71,8 +72,8 @@ public class BeanToBeanCopier<S, T> extends AbsCopier<S, T> {
} }
// 检查源对象属性是否过滤属性 // 检查源对象属性是否过滤属性
Object sValue = sDesc.getValue(this.source); Object sValue = sDesc.getValue(this.source, copyOptions.ignoreError);
if (!copyOptions.testPropertyFilter(sDesc.getField(), sValue)) { if (!this.copyOptions.testPropertyFilter(sDesc.getField(), sValue)) {
return; return;
} }
@ -90,8 +91,8 @@ public class BeanToBeanCopier<S, T> extends AbsCopier<S, T> {
// 检查目标字段可写性 // 检查目标字段可写性
// 目标字段检查放在键值对编辑之后因为键可能被编辑修改 // 目标字段检查放在键值对编辑之后因为键可能被编辑修改
final PropDesc tDesc = this.copyOptions.findPropDesc(targetPropDescMap, sFieldName); final PropDesc tDesc = copyOptions.findPropDesc(targetPropDescMap, sFieldName);
if (null == tDesc || !tDesc.isWritable(this.copyOptions.transientSupport)) { if (null == tDesc || !tDesc.isWritable(copyOptions.transientSupport)) {
// 字段不可写跳过之 // 字段不可写跳过之
return; return;
} }
@ -99,7 +100,7 @@ public class BeanToBeanCopier<S, T> extends AbsCopier<S, T> {
// 获取目标字段真实类型并转换源值 // 获取目标字段真实类型并转换源值
final Type fieldType = TypeUtil.getActualType(this.targetType, tDesc.getFieldType()); final Type fieldType = TypeUtil.getActualType(this.targetType, tDesc.getFieldType());
//sValue = Convert.convertWithCheck(fieldType, sValue, null, this.copyOptions.ignoreError); //sValue = Convert.convertWithCheck(fieldType, sValue, null, this.copyOptions.ignoreError);
sValue = this.copyOptions.convertField(fieldType, sValue); sValue = copyOptions.convertField(fieldType, sValue);
// 目标赋值 // 目标赋值
tDesc.setValue(this.target, sValue, copyOptions.ignoreNullValue, copyOptions.ignoreError, copyOptions.override); tDesc.setValue(this.target, sValue, copyOptions.ignoreNullValue, copyOptions.ignoreError, copyOptions.override);

View File

@ -54,6 +54,7 @@ public class BeanToMapCopier extends AbsCopier<Object, Map> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Map copy() { public Map copy() {
final CopyOptions copyOptions = this.copyOptions;
Class<?> actualEditable = source.getClass(); Class<?> actualEditable = source.getClass();
if (null != copyOptions.editable) { if (null != copyOptions.editable) {
// 检查限制类是否为target的父类或接口 // 检查限制类是否为target的父类或接口
@ -70,7 +71,7 @@ public class BeanToMapCopier extends AbsCopier<Object, Map> {
} }
// 检查源对象属性是否过滤属性 // 检查源对象属性是否过滤属性
Object sValue = sDesc.getValue(this.source); Object sValue = sDesc.getValue(this.source, copyOptions.ignoreError);
if (!copyOptions.testPropertyFilter(sDesc.getField(), sValue)) { if (!copyOptions.testPropertyFilter(sDesc.getField(), sValue)) {
return; return;
} }
@ -91,7 +92,7 @@ public class BeanToMapCopier extends AbsCopier<Object, Map> {
final Type[] typeArguments = TypeUtil.getTypeArguments(this.targetType); final Type[] typeArguments = TypeUtil.getTypeArguments(this.targetType);
if(null != typeArguments && typeArguments.length > 1){ if(null != typeArguments && typeArguments.length > 1){
//sValue = Convert.convertWithCheck(typeArguments[1], sValue, null, this.copyOptions.ignoreError); //sValue = Convert.convertWithCheck(typeArguments[1], sValue, null, this.copyOptions.ignoreError);
sValue = this.copyOptions.convertField(typeArguments[1], sValue); sValue = copyOptions.convertField(typeArguments[1], sValue);
} }
// 目标赋值 // 目标赋值

View File

@ -20,7 +20,6 @@ import org.dromara.hutool.core.bean.BeanDesc;
import org.dromara.hutool.core.bean.BeanUtil; import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.bean.PropDesc; import org.dromara.hutool.core.bean.PropDesc;
import org.dromara.hutool.core.bean.copier.ValueProvider; import org.dromara.hutool.core.bean.copier.ValueProvider;
import org.dromara.hutool.core.convert.ConvertUtil;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -61,7 +60,7 @@ public class BeanValueProvider implements ValueProvider<String> {
public Object value(final String key, final Type valueType) { public Object value(final String key, final Type valueType) {
final PropDesc prop = beanDesc.getProp(key); final PropDesc prop = beanDesc.getProp(key);
if (null != prop) { if (null != prop) {
return ConvertUtil.convert(valueType, prop.getValue(bean)); return prop.getValue(bean, valueType, false);
} }
return null; return null;
} }

View File

@ -72,7 +72,7 @@ public class BeanMap implements Map<String, Object> {
@Override @Override
public boolean containsValue(final Object value) { public boolean containsValue(final Object value) {
for (final PropDesc propDesc : this.propDescMap.values()) { for (final PropDesc propDesc : this.propDescMap.values()) {
if (ObjUtil.equals(propDesc.getValue(bean), value)) { if (ObjUtil.equals(propDesc.getValue(bean, false), value)) {
return true; return true;
} }
} }
@ -83,7 +83,7 @@ public class BeanMap implements Map<String, Object> {
public Object get(final Object key) { public Object get(final Object key) {
final PropDesc propDesc = this.propDescMap.get(key); final PropDesc propDesc = this.propDescMap.get(key);
if (null != propDesc) { if (null != propDesc) {
return propDesc.getValue(bean); return propDesc.getValue(bean, false);
} }
return null; return null;
} }
@ -102,7 +102,7 @@ public class BeanMap implements Map<String, Object> {
public Object put(final String key, final Object value) { public Object put(final String key, final Object value) {
final PropDesc propDesc = this.propDescMap.get(key); final PropDesc propDesc = this.propDescMap.get(key);
if (null != propDesc) { if (null != propDesc) {
final Object oldValue = propDesc.getValue(bean); final Object oldValue = propDesc.getValue(bean, false);
propDesc.setValue(bean, value); propDesc.setValue(bean, value);
return oldValue; return oldValue;
} }
@ -143,7 +143,7 @@ public class BeanMap implements Map<String, Object> {
public Collection<Object> values() { public Collection<Object> values() {
final List<Object> list = new ArrayList<>(size()); final List<Object> list = new ArrayList<>(size());
for (final PropDesc propDesc : this.propDescMap.values()) { for (final PropDesc propDesc : this.propDescMap.values()) {
list.add(propDesc.getValue(bean)); list.add(propDesc.getValue(bean, false));
} }
return list; return list;
} }
@ -151,7 +151,7 @@ public class BeanMap implements Map<String, Object> {
@Override @Override
public Set<Entry<String, Object>> entrySet() { public Set<Entry<String, Object>> entrySet() {
final HashSet<Entry<String, Object>> set = new HashSet<>(size(), 1); final HashSet<Entry<String, Object>> set = new HashSet<>(size(), 1);
this.propDescMap.forEach((key, propDesc) -> set.add(new AbstractMap.SimpleEntry<>(key, propDesc.getValue(bean)))); this.propDescMap.forEach((key, propDesc) -> set.add(new AbstractMap.SimpleEntry<>(key, propDesc.getValue(bean, false))));
return set; return set;
} }
} }

View File

@ -97,7 +97,7 @@ public class BeanDescTest {
desc.getProp("name").setValue(user, "张三"); desc.getProp("name").setValue(user, "张三");
Assertions.assertEquals("张三", user.getName()); Assertions.assertEquals("张三", user.getName());
final Object value = desc.getProp("name").getValue(user); final Object value = desc.getProp("name").getValue(user, false);
Assertions.assertEquals("张三", value); Assertions.assertEquals("张三", value);
} }
@ -108,12 +108,12 @@ public class BeanDescTest {
final User user = new User(); final User user = new User();
desc.getProp("name").setValue(user, "张三"); desc.getProp("name").setValue(user, "张三");
Assertions.assertEquals("张三", user.getName()); Assertions.assertEquals("张三", user.getName());
Object value = desc.getProp("name").getValue(user); Object value = desc.getProp("name").getValue(user, false);
Assertions.assertEquals("张三", value); Assertions.assertEquals("张三", value);
desc.getProp("admin").setValue(user, true); desc.getProp("admin").setValue(user, true);
Assertions.assertTrue(user.isAdmin()); Assertions.assertTrue(user.isAdmin());
value = desc.getProp("admin").getValue(user); value = desc.getProp("admin").getValue(user, false);
Assertions.assertEquals(true, value); Assertions.assertEquals(true, value);
} }