增加MapValueProviderRecordConverter并支持Record转换(issue#3985@Github)

This commit is contained in:
Looly
2025-07-02 10:41:21 +08:00
parent d5bb6b2adb
commit da7d6b9d81
5 changed files with 99 additions and 5 deletions

View File

@@ -6,6 +6,7 @@
### 🐣新特性 ### 🐣新特性
* 【captcha】 `MathGenerator`四则运算方式支持不生成负数结果pr#1363@Gitee * 【captcha】 `MathGenerator`四则运算方式支持不生成负数结果pr#1363@Gitee
* 【core 】 增加`MapValueProvider``RecordConverter`并支持Record转换issue#3985@Github
### 🐞Bug修复 ### 🐞Bug修复
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,38 @@
package cn.hutool.core.bean.copier.provider;
import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.convert.Convert;
import java.lang.reflect.Type;
import java.util.Map;
/**
* Map值提供者
*
* @author Looly
* @since 5.8.40
*/
@SuppressWarnings("rawtypes")
public class MapValueProvider implements ValueProvider<String> {
private final Map map;
/**
* 构造
*
* @param map map
*/
public MapValueProvider(final Map map) {
this.map = map;
}
@Override
public Object value(String key, Type valueType) {
return Convert.convert(valueType, map.get(key));
}
@Override
public boolean containsKey(String key) {
return map.containsKey(key);
}
}

View File

@@ -12,8 +12,8 @@ import java.util.Map;
* 抽象转换器提供通用的转换逻辑同时通过convertInternal实现对应类型的专属逻辑<br> * 抽象转换器提供通用的转换逻辑同时通过convertInternal实现对应类型的专属逻辑<br>
* 转换器不会抛出转换异常,转换失败时会返回{@code null} * 转换器不会抛出转换异常,转换失败时会返回{@code null}
* *
* @param <T> 转换的目标类型
* @author Looly * @author Looly
*
*/ */
public abstract class AbstractConverter<T> implements Converter<T>, Serializable { public abstract class AbstractConverter<T> implements Converter<T>, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@@ -1,6 +1,7 @@
package cn.hutool.core.convert; package cn.hutool.core.convert;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.RecordUtil;
import cn.hutool.core.convert.impl.*; import cn.hutool.core.convert.impl.*;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
@@ -346,6 +347,12 @@ public class ConverterRegistry implements Serializable {
return ReflectUtil.newInstanceIfPossible(rowType); return ReflectUtil.newInstanceIfPossible(rowType);
} }
// record
// issue#3985@Github since 5.8.40
if(RecordUtil.isRecord(rowType)){
return (T) new RecordConverter(rowType).convert(value, defaultValue);
}
// 表示非需要特殊转换的对象 // 表示非需要特殊转换的对象
return null; return null;
} }

View File

@@ -0,0 +1,48 @@
package cn.hutool.core.convert.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.RecordUtil;
import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.bean.copier.provider.BeanValueProvider;
import cn.hutool.core.bean.copier.provider.MapValueProvider;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.convert.Converter;
import java.util.Map;
/**
* Record转换器
*
* @author looly
*/
public class RecordConverter implements Converter<Object> {
private final Class<?> recordClass;
/**
* 构造
* @param recordClass Record类
*/
public RecordConverter(Class<?> recordClass) {
this.recordClass = recordClass;
}
@SuppressWarnings("unchecked")
@Override
public Object convert(Object value, Object defaultValue) throws IllegalArgumentException {
ValueProvider<String> valueProvider = null;
if (value instanceof ValueProvider) {
valueProvider = (ValueProvider<String>) value;
} else if (value instanceof Map) {
valueProvider = new MapValueProvider((Map<String, ?>) value);
} else if (BeanUtil.isReadableBean(value.getClass())) {
valueProvider = new BeanValueProvider(value, false, false);
}
if (null != valueProvider) {
return RecordUtil.newInstance(recordClass, valueProvider);
}
throw new ConvertException("Unsupported source type: [{}] to [{}]", value.getClass(), recordClass);
}
}