mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix converter
This commit is contained in:
parent
1473d4625f
commit
e3d5c2756c
@ -1,7 +1,7 @@
|
|||||||
package cn.hutool.core.bean.copier;
|
package cn.hutool.core.bean.copier;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.convert.TypeConverter;
|
import cn.hutool.core.convert.Converter;
|
||||||
import cn.hutool.core.lang.func.Editor;
|
import cn.hutool.core.lang.func.Editor;
|
||||||
import cn.hutool.core.lang.func.Func1;
|
import cn.hutool.core.lang.func.Func1;
|
||||||
import cn.hutool.core.lang.func.LambdaUtil;
|
import cn.hutool.core.lang.func.LambdaUtil;
|
||||||
@ -70,7 +70,7 @@ public class CopyOptions implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 自定义类型转换器,默认使用全局万能转换器转换
|
* 自定义类型转换器,默认使用全局万能转换器转换
|
||||||
*/
|
*/
|
||||||
protected TypeConverter converter = (type, value) ->
|
protected Converter converter = (type, value) ->
|
||||||
Convert.convertWithCheck(type, value, null, ignoreError);
|
Convert.convertWithCheck(type, value, null, ignoreError);
|
||||||
|
|
||||||
//region create
|
//region create
|
||||||
@ -308,7 +308,7 @@ public class CopyOptions implements Serializable {
|
|||||||
* @return this
|
* @return this
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public CopyOptions setConverter(final TypeConverter converter) {
|
public CopyOptions setConverter(final Converter converter) {
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* @author Looly
|
* @author Looly
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractConverter implements TypeConverter, Serializable {
|
public abstract class AbstractConverter implements Converter, Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -532,7 +532,11 @@ public class Convert {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <E extends Enum<E>> E toEnum(final Class<E> clazz, final Object value, final E defaultValue) {
|
public static <E extends Enum<E>> E toEnum(final Class<E> clazz, final Object value, final E defaultValue) {
|
||||||
return (E) (new EnumConverter(clazz)).convertQuietly(value, defaultValue);
|
try{
|
||||||
|
return (E) (new EnumConverter()).convert(clazz, value);
|
||||||
|
} catch (final Exception ignore){
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -558,7 +562,7 @@ public class Convert {
|
|||||||
* @since 3.0.8
|
* @since 3.0.8
|
||||||
*/
|
*/
|
||||||
public static Collection<?> toCollection(final Class<?> collectionType, final Class<?> elementType, final Object value) {
|
public static Collection<?> toCollection(final Class<?> collectionType, final Class<?> elementType, final Object value) {
|
||||||
return new CollectionConverter(collectionType, elementType).convert(value, null);
|
return new CollectionConverter().convert(collectionType, elementType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -613,7 +617,7 @@ public class Convert {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <K, V> Map<K, V> toMap(final Class<K> keyType, final Class<V> valueType, final Object value) {
|
public static <K, V> Map<K, V> toMap(final Class<K> keyType, final Class<V> valueType, final Object value) {
|
||||||
return (Map<K, V>) new MapConverter(HashMap.class, keyType, valueType).convert(value, null);
|
return (Map<K, V>) new MapConverter().convert(HashMap.class, keyType, valueType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,23 +1,28 @@
|
|||||||
package cn.hutool.core.convert;
|
package cn.hutool.core.convert;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换器接口,实现类型转换
|
* 类型转换接口函数,根据给定的值和目标类型,由用户自定义转换规则。
|
||||||
*
|
*
|
||||||
* @param <T> 转换到的目标类型
|
* @author looly
|
||||||
* @author Looly
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public interface Converter<T> {
|
@FunctionalInterface
|
||||||
|
public interface Converter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为指定类型<br>
|
* 转换为指定类型<br>
|
||||||
* 如果类型无法确定,将读取默认值的类型做为目标类型
|
* 如果类型无法确定,将读取默认值的类型做为目标类型
|
||||||
*
|
*
|
||||||
|
* @param targetType 目标Type,非泛型类使用
|
||||||
* @param value 原始值
|
* @param value 原始值
|
||||||
* @param defaultValue 默认值
|
|
||||||
* @return 转换后的值
|
* @return 转换后的值
|
||||||
* @throws IllegalArgumentException 无法确定目标类型,且默认值为{@code null},无法确定类型
|
* @throws ConvertException 转换无法正常完成或转换异常时抛出此异常
|
||||||
*/
|
*/
|
||||||
T convert(Object value, T defaultValue) throws IllegalArgumentException;
|
Object convert(Type targetType, Object value) throws ConvertException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换值为指定类型,可选是否不抛异常转换<br>
|
* 转换值为指定类型,可选是否不抛异常转换<br>
|
||||||
@ -25,19 +30,10 @@ public interface Converter<T> {
|
|||||||
*
|
*
|
||||||
* @param value 值
|
* @param value 值
|
||||||
* @param defaultValue 默认值
|
* @param defaultValue 默认值
|
||||||
* @param quietly 是否静默转换,true不抛异常
|
|
||||||
* @return 转换后的值
|
* @return 转换后的值
|
||||||
* @since 5.8.0
|
|
||||||
* @see #convert(Object, Object)
|
|
||||||
*/
|
*/
|
||||||
default T convertWithCheck(final Object value, final T defaultValue, final boolean quietly) {
|
@SuppressWarnings("unchecked")
|
||||||
try {
|
default <T> T convert(final Type targetType, final Object value, final T defaultValue) {
|
||||||
return convert(value, defaultValue);
|
return ObjUtil.defaultIfNull((T)convert(targetType, value), defaultValue);
|
||||||
} catch (final Exception e) {
|
|
||||||
if(quietly){
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ import cn.hutool.core.convert.impl.UUIDConverter;
|
|||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.lang.Opt;
|
import cn.hutool.core.lang.Opt;
|
||||||
import cn.hutool.core.reflect.ClassUtil;
|
import cn.hutool.core.reflect.ClassUtil;
|
||||||
import cn.hutool.core.reflect.ConstructorUtil;
|
|
||||||
import cn.hutool.core.reflect.TypeReference;
|
import cn.hutool.core.reflect.TypeReference;
|
||||||
import cn.hutool.core.reflect.TypeUtil;
|
import cn.hutool.core.reflect.TypeUtil;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
@ -97,11 +96,11 @@ public class ConverterRegistry implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 默认类型转换器
|
* 默认类型转换器
|
||||||
*/
|
*/
|
||||||
private Map<Type, Converter<?>> defaultConverterMap;
|
private Map<Type, Converter> defaultConverterMap;
|
||||||
/**
|
/**
|
||||||
* 用户自定义类型转换器
|
* 用户自定义类型转换器
|
||||||
*/
|
*/
|
||||||
private volatile Map<Type, Converter<?>> customConverterMap;
|
private volatile Map<Type, Converter> customConverterMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
|
* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
|
||||||
@ -140,23 +139,12 @@ public class ConverterRegistry implements Serializable {
|
|||||||
if (null != type) {
|
if (null != type) {
|
||||||
putCustom(type, converter);
|
putCustom(type, converter);
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception ignore) {
|
||||||
// 忽略注册失败的
|
// 忽略注册失败的
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 登记自定义转换器
|
|
||||||
*
|
|
||||||
* @param type 转换的目标类型
|
|
||||||
* @param converterClass 转换器类,必须有默认构造方法
|
|
||||||
* @return ConverterRegistry
|
|
||||||
*/
|
|
||||||
public ConverterRegistry putCustom(final Type type, final Class<? extends Converter<?>> converterClass) {
|
|
||||||
return putCustom(type, ConstructorUtil.newInstance(converterClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登记自定义转换器
|
* 登记自定义转换器
|
||||||
*
|
*
|
||||||
@ -164,7 +152,7 @@ public class ConverterRegistry implements Serializable {
|
|||||||
* @param converter 转换器
|
* @param converter 转换器
|
||||||
* @return ConverterRegistry
|
* @return ConverterRegistry
|
||||||
*/
|
*/
|
||||||
public ConverterRegistry putCustom(final Type type, final Converter<?> converter) {
|
public ConverterRegistry putCustom(final Type type, final Converter converter) {
|
||||||
if (null == customConverterMap) {
|
if (null == customConverterMap) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (null == customConverterMap) {
|
if (null == customConverterMap) {
|
||||||
@ -179,13 +167,12 @@ public class ConverterRegistry implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 获得转换器<br>
|
* 获得转换器<br>
|
||||||
*
|
*
|
||||||
* @param <T> 转换的目标类型
|
|
||||||
* @param type 类型
|
* @param type 类型
|
||||||
* @param isCustomFirst 是否自定义转换器优先
|
* @param isCustomFirst 是否自定义转换器优先
|
||||||
* @return 转换器
|
* @return 转换器
|
||||||
*/
|
*/
|
||||||
public <T> Converter<T> getConverter(final Type type, final boolean isCustomFirst) {
|
public Converter getConverter(final Type type, final boolean isCustomFirst) {
|
||||||
Converter<T> converter;
|
Converter converter;
|
||||||
if (isCustomFirst) {
|
if (isCustomFirst) {
|
||||||
converter = this.getCustomConverter(type);
|
converter = this.getCustomConverter(type);
|
||||||
if (null == converter) {
|
if (null == converter) {
|
||||||
@ -203,25 +190,21 @@ public class ConverterRegistry implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 获得默认转换器
|
* 获得默认转换器
|
||||||
*
|
*
|
||||||
* @param <T> 转换的目标类型(转换器转换到的类型)
|
|
||||||
* @param type 类型
|
* @param type 类型
|
||||||
* @return 转换器
|
* @return 转换器
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public Converter getDefaultConverter(final Type type) {
|
||||||
public <T> Converter<T> getDefaultConverter(final Type type) {
|
return (null == defaultConverterMap) ? null : defaultConverterMap.get(type);
|
||||||
return (null == defaultConverterMap) ? null : (Converter<T>) defaultConverterMap.get(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得自定义转换器
|
* 获得自定义转换器
|
||||||
*
|
*
|
||||||
* @param <T> 转换的目标类型(转换器转换到的类型)
|
|
||||||
* @param type 类型
|
* @param type 类型
|
||||||
* @return 转换器
|
* @return 转换器
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public Converter getCustomConverter(final Type type) {
|
||||||
public <T> Converter<T> getCustomConverter(final Type type) {
|
return (null == customConverterMap) ? null : customConverterMap.get(type);
|
||||||
return (null == customConverterMap) ? null : (Converter<T>) customConverterMap.get(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,12 +236,11 @@ public class ConverterRegistry implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 标准转换器
|
// 标准转换器
|
||||||
final Converter<T> converter = getConverter(type, isCustomFirst);
|
final Converter converter = getConverter(type, isCustomFirst);
|
||||||
if (null != converter) {
|
if (null != converter) {
|
||||||
return converter.convert(value, defaultValue);
|
return converter.convert(type, value, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Class<T> rowType = (Class<T>) TypeUtil.getClass(type);
|
Class<T> rowType = (Class<T>) TypeUtil.getClass(type);
|
||||||
if (null == rowType) {
|
if (null == rowType) {
|
||||||
if (null != defaultValue) {
|
if (null != defaultValue) {
|
||||||
@ -277,7 +259,7 @@ public class ConverterRegistry implements Serializable {
|
|||||||
|
|
||||||
// 尝试转Bean
|
// 尝试转Bean
|
||||||
if (BeanUtil.isBean(rowType)) {
|
if (BeanUtil.isBean(rowType)) {
|
||||||
return new BeanConverter<T>(type).convert(value, defaultValue);
|
return (T) new BeanConverter().convert(type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 无法转换
|
// 无法转换
|
||||||
@ -339,14 +321,14 @@ public class ConverterRegistry implements Serializable {
|
|||||||
|
|
||||||
// 集合转换(不可以默认强转)
|
// 集合转换(不可以默认强转)
|
||||||
if (Collection.class.isAssignableFrom(rowType)) {
|
if (Collection.class.isAssignableFrom(rowType)) {
|
||||||
final CollectionConverter collectionConverter = new CollectionConverter(type);
|
final CollectionConverter collectionConverter = new CollectionConverter();
|
||||||
return (T) collectionConverter.convert(value, (Collection<?>) defaultValue);
|
return (T) collectionConverter.convert(type, value, (Collection<?>) defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map类型(不可以默认强转)
|
// Map类型(不可以默认强转)
|
||||||
if (Map.class.isAssignableFrom(rowType)) {
|
if (Map.class.isAssignableFrom(rowType)) {
|
||||||
final MapConverter mapConverter = new MapConverter(type);
|
final MapConverter mapConverter = new MapConverter();
|
||||||
return (T) mapConverter.convert(value, (Map<?, ?>) defaultValue);
|
return (T) mapConverter.convert(type, value, (Map<?, ?>) defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认强转
|
// 默认强转
|
||||||
@ -356,13 +338,12 @@ public class ConverterRegistry implements Serializable {
|
|||||||
|
|
||||||
// 枚举转换
|
// 枚举转换
|
||||||
if (rowType.isEnum()) {
|
if (rowType.isEnum()) {
|
||||||
return (T) new EnumConverter(rowType).convert(value, defaultValue);
|
return EnumConverter.INSTANCE.convert(type, value, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数组转换
|
// 数组转换
|
||||||
if (rowType.isArray()) {
|
if (rowType.isArray()) {
|
||||||
final ArrayConverter arrayConverter = new ArrayConverter(rowType);
|
return ArrayConverter.INSTANCE.convert(type, value, defaultValue);
|
||||||
return (T) arrayConverter.convert(value, defaultValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表示非需要特殊转换的对象
|
// 表示非需要特殊转换的对象
|
||||||
@ -378,32 +359,32 @@ public class ConverterRegistry implements Serializable {
|
|||||||
defaultConverterMap = new ConcurrentHashMap<>();
|
defaultConverterMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
// 原始类型转换器
|
// 原始类型转换器
|
||||||
defaultConverterMap.put(int.class, new PrimitiveConverter(int.class));
|
defaultConverterMap.put(int.class, PrimitiveConverter.INSTANCE);
|
||||||
defaultConverterMap.put(long.class, new PrimitiveConverter(long.class));
|
defaultConverterMap.put(long.class, PrimitiveConverter.INSTANCE);
|
||||||
defaultConverterMap.put(byte.class, new PrimitiveConverter(byte.class));
|
defaultConverterMap.put(byte.class, PrimitiveConverter.INSTANCE);
|
||||||
defaultConverterMap.put(short.class, new PrimitiveConverter(short.class));
|
defaultConverterMap.put(short.class, PrimitiveConverter.INSTANCE);
|
||||||
defaultConverterMap.put(float.class, new PrimitiveConverter(float.class));
|
defaultConverterMap.put(float.class, PrimitiveConverter.INSTANCE);
|
||||||
defaultConverterMap.put(double.class, new PrimitiveConverter(double.class));
|
defaultConverterMap.put(double.class, PrimitiveConverter.INSTANCE);
|
||||||
defaultConverterMap.put(char.class, new PrimitiveConverter(char.class));
|
defaultConverterMap.put(char.class, PrimitiveConverter.INSTANCE);
|
||||||
defaultConverterMap.put(boolean.class, new PrimitiveConverter(boolean.class));
|
defaultConverterMap.put(boolean.class, PrimitiveConverter.INSTANCE);
|
||||||
|
|
||||||
// 包装类转换器
|
// 包装类转换器
|
||||||
defaultConverterMap.put(Number.class, new NumberConverter());
|
defaultConverterMap.put(Number.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(Integer.class, new NumberConverter(Integer.class));
|
defaultConverterMap.put(Integer.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(AtomicInteger.class, new NumberConverter(AtomicInteger.class));// since 3.0.8
|
defaultConverterMap.put(AtomicInteger.class, NumberConverter.INSTANCE);// since 3.0.8
|
||||||
defaultConverterMap.put(Long.class, new NumberConverter(Long.class));
|
defaultConverterMap.put(Long.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(LongAdder.class, new NumberConverter(LongAdder.class));
|
defaultConverterMap.put(LongAdder.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(AtomicLong.class, new NumberConverter(AtomicLong.class));// since 3.0.8
|
defaultConverterMap.put(AtomicLong.class, NumberConverter.INSTANCE);// since 3.0.8
|
||||||
defaultConverterMap.put(Byte.class, new NumberConverter(Byte.class));
|
defaultConverterMap.put(Byte.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(Short.class, new NumberConverter(Short.class));
|
defaultConverterMap.put(Short.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(Float.class, new NumberConverter(Float.class));
|
defaultConverterMap.put(Float.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(Double.class, new NumberConverter(Double.class));
|
defaultConverterMap.put(Double.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(DoubleAdder.class, new NumberConverter(DoubleAdder.class));
|
defaultConverterMap.put(DoubleAdder.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(Character.class, new CharacterConverter());
|
defaultConverterMap.put(Character.class, new CharacterConverter());
|
||||||
defaultConverterMap.put(Boolean.class, new BooleanConverter());
|
defaultConverterMap.put(Boolean.class, new BooleanConverter());
|
||||||
defaultConverterMap.put(AtomicBoolean.class, new AtomicBooleanConverter());// since 3.0.8
|
defaultConverterMap.put(AtomicBoolean.class, new AtomicBooleanConverter());// since 3.0.8
|
||||||
defaultConverterMap.put(BigDecimal.class, new NumberConverter(BigDecimal.class));
|
defaultConverterMap.put(BigDecimal.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(BigInteger.class, new NumberConverter(BigInteger.class));
|
defaultConverterMap.put(BigInteger.class, NumberConverter.INSTANCE);
|
||||||
defaultConverterMap.put(CharSequence.class, new StringConverter());
|
defaultConverterMap.put(CharSequence.class, new StringConverter());
|
||||||
defaultConverterMap.put(String.class, new StringConverter());
|
defaultConverterMap.put(String.class, new StringConverter());
|
||||||
|
|
||||||
@ -413,27 +394,27 @@ public class ConverterRegistry implements Serializable {
|
|||||||
|
|
||||||
// 日期时间
|
// 日期时间
|
||||||
defaultConverterMap.put(Calendar.class, new CalendarConverter());
|
defaultConverterMap.put(Calendar.class, new CalendarConverter());
|
||||||
defaultConverterMap.put(java.util.Date.class, new DateConverter(java.util.Date.class));
|
defaultConverterMap.put(java.util.Date.class, DateConverter.INSTANCE);
|
||||||
defaultConverterMap.put(DateTime.class, new DateConverter(DateTime.class));
|
defaultConverterMap.put(DateTime.class, DateConverter.INSTANCE);
|
||||||
defaultConverterMap.put(java.sql.Date.class, new DateConverter(java.sql.Date.class));
|
defaultConverterMap.put(java.sql.Date.class, DateConverter.INSTANCE);
|
||||||
defaultConverterMap.put(java.sql.Time.class, new DateConverter(java.sql.Time.class));
|
defaultConverterMap.put(java.sql.Time.class, DateConverter.INSTANCE);
|
||||||
defaultConverterMap.put(java.sql.Timestamp.class, new DateConverter(java.sql.Timestamp.class));
|
defaultConverterMap.put(java.sql.Timestamp.class, DateConverter.INSTANCE);
|
||||||
|
|
||||||
// 日期时间 JDK8+(since 5.0.0)
|
// 日期时间 JDK8+(since 5.0.0)
|
||||||
defaultConverterMap.put(TemporalAccessor.class, new TemporalAccessorConverter(Instant.class));
|
defaultConverterMap.put(TemporalAccessor.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(Instant.class, new TemporalAccessorConverter(Instant.class));
|
defaultConverterMap.put(Instant.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(LocalDateTime.class, new TemporalAccessorConverter(LocalDateTime.class));
|
defaultConverterMap.put(LocalDateTime.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(LocalDate.class, new TemporalAccessorConverter(LocalDate.class));
|
defaultConverterMap.put(LocalDate.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(LocalTime.class, new TemporalAccessorConverter(LocalTime.class));
|
defaultConverterMap.put(LocalTime.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(ZonedDateTime.class, new TemporalAccessorConverter(ZonedDateTime.class));
|
defaultConverterMap.put(ZonedDateTime.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(OffsetDateTime.class, new TemporalAccessorConverter(OffsetDateTime.class));
|
defaultConverterMap.put(OffsetDateTime.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(OffsetTime.class, new TemporalAccessorConverter(OffsetTime.class));
|
defaultConverterMap.put(OffsetTime.class, TemporalAccessorConverter.INSTANCE);
|
||||||
defaultConverterMap.put(Period.class, new PeriodConverter());
|
defaultConverterMap.put(Period.class, new PeriodConverter());
|
||||||
defaultConverterMap.put(Duration.class, new DurationConverter());
|
defaultConverterMap.put(Duration.class, new DurationConverter());
|
||||||
|
|
||||||
// Reference
|
// Reference
|
||||||
defaultConverterMap.put(WeakReference.class, new ReferenceConverter(WeakReference.class));// since 3.0.8
|
defaultConverterMap.put(WeakReference.class, ReferenceConverter.INSTANCE);// since 3.0.8
|
||||||
defaultConverterMap.put(SoftReference.class, new ReferenceConverter(SoftReference.class));// since 3.0.8
|
defaultConverterMap.put(SoftReference.class, ReferenceConverter.INSTANCE);// since 3.0.8
|
||||||
defaultConverterMap.put(AtomicReference.class, new AtomicReferenceConverter());// since 3.0.8
|
defaultConverterMap.put(AtomicReference.class, new AtomicReferenceConverter());// since 3.0.8
|
||||||
|
|
||||||
//AtomicXXXArray,since 5.4.5
|
//AtomicXXXArray,since 5.4.5
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package cn.hutool.core.convert;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 类型转换接口函数,根据给定的值和目标类型,由用户自定义转换规则。
|
|
||||||
*
|
|
||||||
* @author looly
|
|
||||||
* @since 5.8.0
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface TypeConverter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换为指定类型<br>
|
|
||||||
* 如果类型无法确定,将读取默认值的类型做为目标类型
|
|
||||||
*
|
|
||||||
* @param targetType 目标Type,非泛型类使用
|
|
||||||
* @param value 原始值
|
|
||||||
* @return 转换后的值
|
|
||||||
* @throws ConvertException 转换无法正常完成或转换异常时抛出此异常
|
|
||||||
*/
|
|
||||||
Object convert(Type targetType, Object value) throws ConvertException;
|
|
||||||
}
|
|
@ -24,6 +24,8 @@ import java.util.List;
|
|||||||
public class ArrayConverter extends AbstractConverter {
|
public class ArrayConverter extends AbstractConverter {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final ArrayConverter INSTANCE = new ArrayConverter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否忽略元素转换错误
|
* 是否忽略元素转换错误
|
||||||
*/
|
*/
|
||||||
|
@ -4,13 +4,15 @@ import cn.hutool.core.bean.BeanUtil;
|
|||||||
import cn.hutool.core.bean.copier.BeanCopier;
|
import cn.hutool.core.bean.copier.BeanCopier;
|
||||||
import cn.hutool.core.bean.copier.CopyOptions;
|
import cn.hutool.core.bean.copier.CopyOptions;
|
||||||
import cn.hutool.core.bean.copier.ValueProvider;
|
import cn.hutool.core.bean.copier.ValueProvider;
|
||||||
import cn.hutool.core.convert.AbstractConverter;
|
|
||||||
import cn.hutool.core.convert.ConvertException;
|
import cn.hutool.core.convert.ConvertException;
|
||||||
|
import cn.hutool.core.convert.Converter;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.map.MapProxy;
|
import cn.hutool.core.map.MapProxy;
|
||||||
import cn.hutool.core.reflect.ConstructorUtil;
|
import cn.hutool.core.reflect.ConstructorUtil;
|
||||||
import cn.hutool.core.reflect.TypeUtil;
|
import cn.hutool.core.reflect.TypeUtil;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -22,60 +24,54 @@ import java.util.Map;
|
|||||||
* ValueProvider =》 Bean
|
* ValueProvider =》 Bean
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param <T> Bean类型
|
|
||||||
* @author Looly
|
* @author Looly
|
||||||
* @since 4.0.2
|
* @since 4.0.2
|
||||||
*/
|
*/
|
||||||
public class BeanConverter<T> extends AbstractConverter {
|
public class BeanConverter implements Converter, Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final Type beanType;
|
|
||||||
private final Class<T> beanClass;
|
|
||||||
private final CopyOptions copyOptions;
|
private final CopyOptions copyOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造,默认转换选项,注入失败的字段忽略
|
* 构造
|
||||||
*
|
|
||||||
* @param beanType 转换成的目标Bean类型
|
|
||||||
*/
|
*/
|
||||||
public BeanConverter(final Type beanType) {
|
public BeanConverter() {
|
||||||
this(beanType, CopyOptions.create().setIgnoreError(true));
|
this(CopyOptions.create().setIgnoreError(true));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造,默认转换选项,注入失败的字段忽略
|
|
||||||
*
|
|
||||||
* @param beanClass 转换成的目标Bean类
|
|
||||||
*/
|
|
||||||
public BeanConverter(final Class<T> beanClass) {
|
|
||||||
this(beanClass, CopyOptions.create().setIgnoreError(true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param beanType 转换成的目标Bean类
|
|
||||||
* @param copyOptions Bean转换选项参数
|
* @param copyOptions Bean转换选项参数
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public BeanConverter(final CopyOptions copyOptions) {
|
||||||
public BeanConverter(final Type beanType, final CopyOptions copyOptions) {
|
|
||||||
this.beanType = beanType;
|
|
||||||
this.beanClass = (Class<T>) TypeUtil.getClass(beanType);
|
|
||||||
this.copyOptions = copyOptions;
|
this.copyOptions = copyOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected T convertInternal(final Class<?> targetClass, final Object value) {
|
public Object convert(Type targetType, Object value) throws ConvertException {
|
||||||
|
Assert.notNull(targetType);
|
||||||
|
if (null == value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> targetClass = TypeUtil.getClass(targetType);
|
||||||
|
Assert.notNull(targetClass, "Target type is not a class!");
|
||||||
|
|
||||||
|
return convertInternal(targetType, targetClass, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object convertInternal(final Type targetType, final Class<?> targetClass, final Object value) {
|
||||||
if (value instanceof Map ||
|
if (value instanceof Map ||
|
||||||
value instanceof ValueProvider ||
|
value instanceof ValueProvider ||
|
||||||
BeanUtil.isBean(value.getClass())) {
|
BeanUtil.isBean(value.getClass())) {
|
||||||
if(value instanceof Map && this.beanClass.isInterface()) {
|
if (value instanceof Map && targetClass.isInterface()) {
|
||||||
// 将Map动态代理为Bean
|
// 将Map动态代理为Bean
|
||||||
return MapProxy.create((Map<?, ?>)value).toProxyBean(this.beanClass);
|
return MapProxy.create((Map<?, ?>) value).toProxyBean(targetClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
//限定被转换对象类型
|
//限定被转换对象类型
|
||||||
return BeanCopier.create(value, ConstructorUtil.newInstanceIfPossible(this.beanClass), this.beanType, this.copyOptions).copy();
|
return BeanCopier.create(value, ConstructorUtil.newInstanceIfPossible(targetClass), targetType, this.copyOptions).copy();
|
||||||
} else if (value instanceof byte[]) {
|
} else if (value instanceof byte[]) {
|
||||||
// 尝试反序列化
|
// 尝试反序列化
|
||||||
return ObjUtil.deserialize((byte[]) value);
|
return ObjUtil.deserialize((byte[]) value);
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package cn.hutool.core.convert.impl;
|
package cn.hutool.core.convert.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.convert.TypeConverter;
|
import cn.hutool.core.convert.Converter;
|
||||||
|
import cn.hutool.core.reflect.TypeReference;
|
||||||
import cn.hutool.core.reflect.TypeUtil;
|
import cn.hutool.core.reflect.TypeUtil;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
@ -13,64 +14,27 @@ import java.util.Collection;
|
|||||||
* @author Looly
|
* @author Looly
|
||||||
* @since 3.0.8
|
* @since 3.0.8
|
||||||
*/
|
*/
|
||||||
public class CollectionConverter implements TypeConverter {
|
public class CollectionConverter implements Converter {
|
||||||
|
|
||||||
/** 集合类型 */
|
|
||||||
private final Type collectionType;
|
|
||||||
/** 集合元素类型 */
|
|
||||||
private final Type elementType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造,默认集合类型使用{@link Collection}
|
|
||||||
*/
|
|
||||||
public CollectionConverter() {
|
|
||||||
this(Collection.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------- Constractor start
|
|
||||||
/**
|
|
||||||
* 构造
|
|
||||||
*
|
|
||||||
* @param collectionType 集合类型
|
|
||||||
*/
|
|
||||||
public CollectionConverter(final Type collectionType) {
|
|
||||||
this(collectionType, TypeUtil.getTypeArgument(collectionType));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造
|
|
||||||
*
|
|
||||||
* @param collectionType 集合类型
|
|
||||||
*/
|
|
||||||
public CollectionConverter(final Class<?> collectionType) {
|
|
||||||
this(collectionType, TypeUtil.getTypeArgument(collectionType));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造
|
|
||||||
*
|
|
||||||
* @param collectionType 集合类型
|
|
||||||
* @param elementType 集合元素类型
|
|
||||||
*/
|
|
||||||
public CollectionConverter(final Type collectionType, final Type elementType) {
|
|
||||||
this.collectionType = collectionType;
|
|
||||||
this.elementType = elementType;
|
|
||||||
}
|
|
||||||
// ---------------------------------------------------------------------------------------------- Constractor end
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<?> convert(final Type targetType, final Object value) {
|
public Collection<?> convert(Type targetType, final Object value) {
|
||||||
return convertInternal(value);
|
if (targetType instanceof TypeReference) {
|
||||||
|
targetType = ((TypeReference<?>) targetType).getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
return convert(targetType, TypeUtil.getTypeArgument(targetType), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部转换
|
* 转换
|
||||||
*
|
*
|
||||||
* @param value 值
|
* @param collectionType 集合类型
|
||||||
|
* @param elementType 集合中元素类型
|
||||||
|
* @param value 被转换的值
|
||||||
* @return 转换后的集合对象
|
* @return 转换后的集合对象
|
||||||
*/
|
*/
|
||||||
protected Collection<?> convertInternal(final Object value) {
|
public Collection<?> convert(final Type collectionType, final Type elementType, final Object value) {
|
||||||
final Collection<Object> collection = CollUtil.create(TypeUtil.getClass(this.collectionType));
|
final Collection<Object> collection = CollUtil.create(TypeUtil.getClass(collectionType));
|
||||||
return CollUtil.addAll(collection, value, this.elementType);
|
return CollUtil.addAll(collection, value, elementType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,20 @@ import java.util.Calendar;
|
|||||||
public class DateConverter extends AbstractConverter {
|
public class DateConverter extends AbstractConverter {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final DateConverter INSTANCE = new DateConverter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日期格式化
|
* 日期格式化
|
||||||
*/
|
*/
|
||||||
private String format;
|
private String format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*/
|
||||||
|
public DateConverter() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
|
@ -25,32 +25,23 @@ import java.util.stream.Collectors;
|
|||||||
public class EnumConverter extends AbstractConverter {
|
public class EnumConverter extends AbstractConverter {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final EnumConverter INSTANCE = new EnumConverter();
|
||||||
|
|
||||||
private static final WeakConcurrentMap<Class<?>, Map<Class<?>, Method>> VALUE_OF_METHOD_CACHE = new WeakConcurrentMap<>();
|
private static final WeakConcurrentMap<Class<?>, Map<Class<?>, Method>> VALUE_OF_METHOD_CACHE = new WeakConcurrentMap<>();
|
||||||
|
|
||||||
private final Class enumClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造
|
|
||||||
*
|
|
||||||
* @param enumClass 转换成的目标Enum类
|
|
||||||
*/
|
|
||||||
public EnumConverter(final Class enumClass) {
|
|
||||||
this.enumClass = enumClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object convertInternal(final Class<?> targetClass, final Object value) {
|
protected Object convertInternal(final Class<?> targetClass, final Object value) {
|
||||||
Enum enumValue = tryConvertEnum(value, this.enumClass);
|
Enum enumValue = tryConvertEnum(value, targetClass);
|
||||||
if (null == enumValue && false == value instanceof String) {
|
if (null == enumValue && false == value instanceof String) {
|
||||||
// 最后尝试先将value转String,再valueOf转换
|
// 最后尝试先将value转String,再valueOf转换
|
||||||
enumValue = Enum.valueOf(this.enumClass, convertToStr(value));
|
enumValue = Enum.valueOf((Class) targetClass, convertToStr(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null != enumValue) {
|
if (null != enumValue) {
|
||||||
return enumValue;
|
return enumValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ConvertException("Can not convert {} to {}", value, this.enumClass);
|
throw new ConvertException("Can not convert {} to {}", value, targetClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package cn.hutool.core.convert.impl;
|
package cn.hutool.core.convert.impl;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.convert.AbstractConverter;
|
import cn.hutool.core.convert.ConvertException;
|
||||||
import cn.hutool.core.convert.ConverterRegistry;
|
import cn.hutool.core.convert.ConverterRegistry;
|
||||||
|
import cn.hutool.core.convert.Converter;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.text.StrUtil;
|
import cn.hutool.core.reflect.TypeReference;
|
||||||
import cn.hutool.core.reflect.TypeUtil;
|
import cn.hutool.core.reflect.TypeUtil;
|
||||||
|
import cn.hutool.core.text.StrUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -17,60 +20,56 @@ import java.util.Objects;
|
|||||||
* @author Looly
|
* @author Looly
|
||||||
* @since 3.0.8
|
* @since 3.0.8
|
||||||
*/
|
*/
|
||||||
public class MapConverter extends AbstractConverter {
|
public class MapConverter implements Converter, Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** Map类型 */
|
|
||||||
private final Type mapType;
|
|
||||||
/** 键类型 */
|
|
||||||
private final Type keyType;
|
|
||||||
/** 值类型 */
|
|
||||||
private final Type valueType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造,Map的key和value泛型类型自动获取
|
|
||||||
*
|
|
||||||
* @param mapType Map类型
|
|
||||||
*/
|
|
||||||
public MapConverter(final Type mapType) {
|
|
||||||
this(mapType, TypeUtil.getTypeArgument(mapType, 0), TypeUtil.getTypeArgument(mapType, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
|
||||||
* @param mapType Map类型
|
|
||||||
* @param keyType 键类型
|
|
||||||
* @param valueType 值类型
|
|
||||||
*/
|
*/
|
||||||
public MapConverter(final Type mapType, final Type keyType, final Type valueType) {
|
public MapConverter() {
|
||||||
this.mapType = mapType;
|
|
||||||
this.keyType = keyType;
|
|
||||||
this.valueType = valueType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
public Object convert(Type targetType, Object value) throws ConvertException {
|
||||||
protected Map<?, ?> convertInternal(final Class<?> targetClass, final Object value) {
|
if (targetType instanceof TypeReference) {
|
||||||
|
targetType = ((TypeReference<?>) targetType).getType();
|
||||||
|
}
|
||||||
|
final Type keyType = TypeUtil.getTypeArgument(targetType, 0);
|
||||||
|
final Type valueType = TypeUtil.getTypeArgument(targetType, 1);
|
||||||
|
|
||||||
|
return convert(targetType, keyType, valueType, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换对象为指定键值类型的指定类型Map
|
||||||
|
*
|
||||||
|
* @param targetType 目标的Map类型
|
||||||
|
* @param keyType 键类型
|
||||||
|
* @param valueType 值类型
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 转换后的Map
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public Map<?, ?> convert(final Type targetType, final Type keyType, final Type valueType, final Object value) {
|
||||||
Map map;
|
Map map;
|
||||||
if (value instanceof Map) {
|
if (value instanceof Map) {
|
||||||
final Class<?> valueClass = value.getClass();
|
final Class<?> valueClass = value.getClass();
|
||||||
if(valueClass.equals(this.mapType)){
|
if (valueClass.equals(targetType)) {
|
||||||
final Type[] typeArguments = TypeUtil.getTypeArguments(valueClass);
|
final Type[] typeArguments = TypeUtil.getTypeArguments(valueClass);
|
||||||
if (null != typeArguments //
|
if (null != typeArguments //
|
||||||
&& 2 == typeArguments.length//
|
&& 2 == typeArguments.length//
|
||||||
&& Objects.equals(this.keyType, typeArguments[0]) //
|
&& Objects.equals(keyType, typeArguments[0]) //
|
||||||
&& Objects.equals(this.valueType, typeArguments[1])) {
|
&& Objects.equals(valueType, typeArguments[1])) {
|
||||||
//对于键值对类型一致的Map对象,不再做转换,直接返回原对象
|
//对于键值对类型一致的Map对象,不再做转换,直接返回原对象
|
||||||
return (Map) value;
|
return (Map) value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map = MapUtil.createMap(TypeUtil.getClass(this.mapType));
|
map = MapUtil.createMap(TypeUtil.getClass(targetType));
|
||||||
convertMapToMap((Map) value, map);
|
convertMapToMap(keyType, valueType, (Map) value, map);
|
||||||
} else if (BeanUtil.isBean(value.getClass())) {
|
} else if (BeanUtil.isBean(value.getClass())) {
|
||||||
map = BeanUtil.beanToMap(value);
|
map = BeanUtil.beanToMap(value);
|
||||||
// 二次转换,转换键值类型
|
// 二次转换,转换键值类型
|
||||||
map = convertInternal(targetClass, map);
|
map = convert(targetType, keyType, valueType, map);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException(StrUtil.format("Unsupport toMap value type: {}", value.getClass().getName()));
|
throw new UnsupportedOperationException(StrUtil.format("Unsupport toMap value type: {}", value.getClass().getName()));
|
||||||
}
|
}
|
||||||
@ -83,11 +82,12 @@ public class MapConverter extends AbstractConverter {
|
|||||||
* @param srcMap 源Map
|
* @param srcMap 源Map
|
||||||
* @param targetMap 目标Map
|
* @param targetMap 目标Map
|
||||||
*/
|
*/
|
||||||
private void convertMapToMap(final Map<?, ?> srcMap, final Map<Object, Object> targetMap) {
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
private void convertMapToMap(Type keyType, Type valueType, final Map<?, ?> srcMap, final Map targetMap) {
|
||||||
final ConverterRegistry convert = ConverterRegistry.getInstance();
|
final ConverterRegistry convert = ConverterRegistry.getInstance();
|
||||||
srcMap.forEach((key, value) -> {
|
srcMap.forEach((key, value) -> {
|
||||||
key = TypeUtil.isUnknown(this.keyType) ? key : convert.convert(this.keyType, key);
|
key = TypeUtil.isUnknown(keyType) ? key : convert.convert(keyType, key);
|
||||||
value = TypeUtil.isUnknown(this.valueType) ? value : convert.convert(this.valueType, value);
|
value = TypeUtil.isUnknown(valueType) ? value : convert.convert(valueType, value);
|
||||||
targetMap.put(key, value);
|
targetMap.put(key, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -39,24 +39,12 @@ import java.util.function.Function;
|
|||||||
public class NumberConverter extends AbstractConverter {
|
public class NumberConverter extends AbstractConverter {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final Class<? extends Number> targetType;
|
public static final NumberConverter INSTANCE = new NumberConverter();
|
||||||
|
|
||||||
public NumberConverter() {
|
|
||||||
this.targetType = Number.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造<br>
|
|
||||||
*
|
|
||||||
* @param clazz 需要转换的数字类型,默认 {@link Number}
|
|
||||||
*/
|
|
||||||
public NumberConverter(final Class<? extends Number> clazz) {
|
|
||||||
this.targetType = (null == clazz) ? Number.class : clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected Number convertInternal(final Class<?> targetClass, final Object value) {
|
protected Number convertInternal(final Class<?> targetClass, final Object value) {
|
||||||
return convert(value, this.targetType, this::convertToStr);
|
return convert(value, (Class<? extends Number>) targetClass, this::convertToStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,8 +3,8 @@ package cn.hutool.core.convert.impl;
|
|||||||
import cn.hutool.core.convert.AbstractConverter;
|
import cn.hutool.core.convert.AbstractConverter;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.convert.ConvertException;
|
import cn.hutool.core.convert.ConvertException;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
|
||||||
import cn.hutool.core.text.StrUtil;
|
import cn.hutool.core.text.StrUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@ -27,6 +27,8 @@ import java.util.function.Function;
|
|||||||
public class PrimitiveConverter extends AbstractConverter {
|
public class PrimitiveConverter extends AbstractConverter {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final PrimitiveConverter INSTANCE = new PrimitiveConverter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造<br>
|
* 构造<br>
|
||||||
*
|
*
|
||||||
|
@ -20,15 +20,7 @@ import java.lang.reflect.Type;
|
|||||||
public class ReferenceConverter extends AbstractConverter {
|
public class ReferenceConverter extends AbstractConverter {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final Class<? extends Reference> targetType;
|
public static ReferenceConverter INSTANCE = new ReferenceConverter();
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造
|
|
||||||
* @param targetType {@link Reference}实现类型
|
|
||||||
*/
|
|
||||||
public ReferenceConverter(final Class<? extends Reference> targetType) {
|
|
||||||
this.targetType = targetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
@ -36,7 +28,7 @@ public class ReferenceConverter extends AbstractConverter {
|
|||||||
|
|
||||||
//尝试将值转换为Reference泛型的类型
|
//尝试将值转换为Reference泛型的类型
|
||||||
Object targetValue = null;
|
Object targetValue = null;
|
||||||
final Type paramType = TypeUtil.getTypeArgument(targetType);
|
final Type paramType = TypeUtil.getTypeArgument(targetClass);
|
||||||
if(false == TypeUtil.isUnknown(paramType)){
|
if(false == TypeUtil.isUnknown(paramType)){
|
||||||
targetValue = ConverterRegistry.getInstance().convert(paramType, value);
|
targetValue = ConverterRegistry.getInstance().convert(paramType, value);
|
||||||
}
|
}
|
||||||
@ -44,13 +36,13 @@ public class ReferenceConverter extends AbstractConverter {
|
|||||||
targetValue = value;
|
targetValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.targetType == WeakReference.class){
|
if(targetClass == WeakReference.class){
|
||||||
return new WeakReference(targetValue);
|
return new WeakReference(targetValue);
|
||||||
}else if(this.targetType == SoftReference.class){
|
}else if(targetClass == SoftReference.class){
|
||||||
return new SoftReference(targetValue);
|
return new SoftReference(targetValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException(StrUtil.format("Unsupport Reference type: {}", this.targetType.getName()));
|
throw new UnsupportedOperationException(StrUtil.format("Unsupport Reference type: {}", targetClass.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,20 @@ import java.util.Objects;
|
|||||||
public class TemporalAccessorConverter extends AbstractConverter {
|
public class TemporalAccessorConverter extends AbstractConverter {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final TemporalAccessorConverter INSTANCE = new TemporalAccessorConverter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日期格式化
|
* 日期格式化
|
||||||
*/
|
*/
|
||||||
private String format;
|
private String format;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*/
|
||||||
|
public TemporalAccessorConverter() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
|
@ -39,8 +39,8 @@ public class ConvertToArrayTest {
|
|||||||
public void toIntArrayTestIgnoreComponentErrorTest() {
|
public void toIntArrayTestIgnoreComponentErrorTest() {
|
||||||
final String[] b = { "a", "1" };
|
final String[] b = { "a", "1" };
|
||||||
|
|
||||||
final ArrayConverter arrayConverter = new ArrayConverter(Integer[].class, true);
|
final ArrayConverter arrayConverter = new ArrayConverter(true);
|
||||||
final Integer[] integerArray = (Integer[]) arrayConverter.convert(b, null);
|
final Integer[] integerArray = arrayConverter.convert(Integer[].class, b, null);
|
||||||
Assert.assertArrayEquals(integerArray, new Integer[]{null, 1});
|
Assert.assertArrayEquals(integerArray, new Integer[]{null, 1});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ public class ConvertToArrayTest {
|
|||||||
//字符串转数组
|
//字符串转数组
|
||||||
final String arrayStr = "1,2,3,4,5";
|
final String arrayStr = "1,2,3,4,5";
|
||||||
//获取Converter类的方法2,自己实例化相应Converter对象
|
//获取Converter类的方法2,自己实例化相应Converter对象
|
||||||
final ArrayConverter c3 = new ArrayConverter(int[].class);
|
final ArrayConverter c3 = new ArrayConverter();
|
||||||
final int[] result3 = (int[]) c3.convert(arrayStr, null);
|
final int[] result3 = c3.convert(int[].class, arrayStr, null);
|
||||||
Assert.assertArrayEquals(new int[]{1,2,3,4,5}, result3);
|
Assert.assertArrayEquals(new int[]{1,2,3,4,5}, result3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package cn.hutool.core.convert;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConverterRegistry 单元测试
|
* ConverterRegistry 单元测试
|
||||||
* @author Looly
|
* @author Looly
|
||||||
@ -12,7 +14,7 @@ public class ConverterRegistryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getConverterTest() {
|
public void getConverterTest() {
|
||||||
final Converter<Object> converter = ConverterRegistry.getInstance().getConverter(CharSequence.class, false);
|
final Converter converter = ConverterRegistry.getInstance().getConverter(CharSequence.class, false);
|
||||||
Assert.assertNotNull(converter);
|
Assert.assertNotNull(converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,14 +28,14 @@ public class ConverterRegistryTest {
|
|||||||
|
|
||||||
//此处做为示例自定义CharSequence转换,因为Hutool中已经提供CharSequence转换,请尽量不要替换
|
//此处做为示例自定义CharSequence转换,因为Hutool中已经提供CharSequence转换,请尽量不要替换
|
||||||
//替换可能引发关联转换异常(例如覆盖CharSequence转换会影响全局)
|
//替换可能引发关联转换异常(例如覆盖CharSequence转换会影响全局)
|
||||||
converterRegistry.putCustom(CharSequence.class, CustomConverter.class);
|
converterRegistry.putCustom(CharSequence.class, new CustomConverter());
|
||||||
result = converterRegistry.convert(CharSequence.class, a);
|
result = converterRegistry.convert(CharSequence.class, a);
|
||||||
Assert.assertEquals("Custom: 454553", result);
|
Assert.assertEquals("Custom: 454553", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CustomConverter implements Converter<CharSequence>{
|
public static class CustomConverter implements Converter{
|
||||||
@Override
|
@Override
|
||||||
public CharSequence convert(final Object value, final CharSequence defaultValue) throws IllegalArgumentException {
|
public Object convert(Type targetType, Object value) throws ConvertException {
|
||||||
return "Custom: " + value.toString();
|
return "Custom: " + value.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,15 @@ public class NumberConverterTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void toDoubleTest(){
|
public void toDoubleTest(){
|
||||||
final NumberConverter numberConverter = new NumberConverter(Double.class);
|
final NumberConverter numberConverter = new NumberConverter();
|
||||||
final Number convert = numberConverter.convert("1,234.55", null);
|
final Number convert = numberConverter.convert(Double.class, "1,234.55", null);
|
||||||
Assert.assertEquals(1234.55D, convert);
|
Assert.assertEquals(1234.55D, convert);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void toIntegerTest(){
|
public void toIntegerTest(){
|
||||||
final NumberConverter numberConverter = new NumberConverter(Integer.class);
|
final NumberConverter numberConverter = new NumberConverter();
|
||||||
final Number convert = numberConverter.convert("1,234.55", null);
|
final Number convert = numberConverter.convert(Integer.class, "1,234.55", null);
|
||||||
Assert.assertEquals(1234, convert);
|
Assert.assertEquals(1234, convert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,14 +24,21 @@ import java.util.List;
|
|||||||
* @author looly
|
* @author looly
|
||||||
* @since 4.2.2
|
* @since 4.2.2
|
||||||
*/
|
*/
|
||||||
public class JSONConverter implements Converter<JSON> {
|
public class JSONConverter implements Converter {
|
||||||
|
|
||||||
|
public static JSONConverter INSTANCE = new JSONConverter();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// 注册到转换中心
|
// 注册到转换中心
|
||||||
final ConverterRegistry registry = ConverterRegistry.getInstance();
|
final ConverterRegistry registry = ConverterRegistry.getInstance();
|
||||||
registry.putCustom(JSON.class, JSONConverter.class);
|
registry.putCustom(JSON.class, INSTANCE);
|
||||||
registry.putCustom(JSONObject.class, JSONConverter.class);
|
registry.putCustom(JSONObject.class, INSTANCE);
|
||||||
registry.putCustom(JSONArray.class, JSONConverter.class);
|
registry.putCustom(JSONArray.class, INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Type targetType, Object value) throws ConvertException {
|
||||||
|
return JSONUtil.parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +49,7 @@ public class JSONConverter implements Converter<JSON> {
|
|||||||
* @return 数组对象
|
* @return 数组对象
|
||||||
*/
|
*/
|
||||||
protected static Object toArray(final JSONArray jsonArray, final Class<?> arrayClass) {
|
protected static Object toArray(final JSONArray jsonArray, final Class<?> arrayClass) {
|
||||||
return new ArrayConverter(arrayClass).convert(jsonArray, null);
|
return ArrayConverter.INSTANCE.convert(arrayClass, jsonArray, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,9 +131,9 @@ public class JSONConverter implements Converter<JSON> {
|
|||||||
if(value instanceof JSONGetter
|
if(value instanceof JSONGetter
|
||||||
&& targetType instanceof Class && BeanUtil.hasSetter((Class<?>) targetType)){
|
&& targetType instanceof Class && BeanUtil.hasSetter((Class<?>) targetType)){
|
||||||
final JSONConfig config = ((JSONGetter<?>) value).getConfig();
|
final JSONConfig config = ((JSONGetter<?>) value).getConfig();
|
||||||
final Converter<T> converter = new BeanConverter<>(targetType,
|
final Converter converter = new BeanConverter(InternalJSONUtil.toCopyOptions(config).setIgnoreError(ignoreError));
|
||||||
InternalJSONUtil.toCopyOptions(config).setIgnoreError(ignoreError));
|
return ignoreError ? converter.convert(targetType, value, null)
|
||||||
return converter.convertWithCheck(value, null, ignoreError);
|
: (T) converter.convert(targetType, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,9 +151,4 @@ public class JSONConverter implements Converter<JSON> {
|
|||||||
|
|
||||||
return targetValue;
|
return targetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSON convert(final Object value, final JSON defaultValue) throws IllegalArgumentException {
|
|
||||||
return JSONUtil.parse(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
package cn.hutool.json;
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
Loading…
x
Reference in New Issue
Block a user