mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix bug
This commit is contained in:
parent
46cffe4ed2
commit
1b0d5d2cf1
@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.7.13 (2021-09-13)
|
||||
# 5.7.13 (2021-09-14)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 CsvReadConfig增加trimField选项(issue#I49M0C@Gitee)
|
||||
@ -17,6 +17,7 @@
|
||||
* 【core 】 修复StrJoiner.append配置丢失问题(issue#I49K1L@Gitee)
|
||||
* 【core 】 修复EscapeUtil特殊字符的hex长度不足导致的问题(issue#I49JU8@Gitee)
|
||||
* 【core 】 修复UrlBuilder对Fragment部分编码问题(issue#I49KAL@Gitee)
|
||||
* 【core 】 修复Enum转换的bug(issue#I49VZB@Gitee)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.core.convert.impl;
|
||||
|
||||
import cn.hutool.core.convert.AbstractConverter;
|
||||
import cn.hutool.core.convert.ConvertException;
|
||||
import cn.hutool.core.lang.EnumItem;
|
||||
import cn.hutool.core.lang.SimpleCache;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
@ -41,10 +42,15 @@ public class EnumConverter extends AbstractConverter<Object> {
|
||||
protected Object convertInternal(Object value) {
|
||||
Enum enumValue = tryConvertEnum(value, this.enumClass);
|
||||
if (null == enumValue && false == value instanceof String) {
|
||||
// 最后尝试valueOf转换
|
||||
// 最后尝试先将value转String,再valueOf转换
|
||||
enumValue = Enum.valueOf(this.enumClass, convertToStr(value));
|
||||
}
|
||||
return enumValue;
|
||||
|
||||
if (null != enumValue) {
|
||||
return enumValue;
|
||||
}
|
||||
|
||||
throw new ConvertException("Can not convert {} to {}", value, this.enumClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -53,9 +59,13 @@ public class EnumConverter extends AbstractConverter<Object> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试找到类似转换的静态方法调用实现转换且优先使用<br>
|
||||
* 约定枚举类应该提供 valueOf(String) 和 valueOf(Integer)用于转换
|
||||
* oriInt /name 转换托底
|
||||
* 尝试转换,转换规则为:
|
||||
* <ul>
|
||||
* <li>如果实现{@link EnumItem}接口,则调用fromInt或fromStr转换</li>
|
||||
* <li>找到类似转换的静态方法调用实现转换且优先使用</li>
|
||||
* <li>约定枚举类应该提供 valueOf(String) 和 valueOf(Integer)用于转换</li>
|
||||
* <li>oriInt /name 转换托底</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param enumClass enum类
|
||||
@ -67,10 +77,9 @@ public class EnumConverter extends AbstractConverter<Object> {
|
||||
}
|
||||
|
||||
// EnumItem实现转换
|
||||
Enum enumResult = null;
|
||||
if (EnumItem.class.isAssignableFrom(enumClass)) {
|
||||
final EnumItem first = (EnumItem) EnumUtil.getEnumAt(enumClass, 0);
|
||||
if(null != first){
|
||||
if (null != first) {
|
||||
if (value instanceof Integer) {
|
||||
return (Enum) first.fromInt((Integer) value);
|
||||
} else if (value instanceof String) {
|
||||
@ -81,14 +90,18 @@ public class EnumConverter extends AbstractConverter<Object> {
|
||||
|
||||
// 用户自定义方法
|
||||
// 查找枚举中所有返回值为目标枚举对象的方法,如果发现方法参数匹配,就执行之
|
||||
final Map<Class<?>, Method> methodMap = getMethodMap(enumClass);
|
||||
if (MapUtil.isNotEmpty(methodMap)) {
|
||||
final Class<?> valueClass = value.getClass();
|
||||
for (Map.Entry<Class<?>, Method> entry : methodMap.entrySet()) {
|
||||
if (ClassUtil.isAssignable(entry.getKey(), valueClass)) {
|
||||
enumResult = ReflectUtil.invokeStatic(entry.getValue(), value);
|
||||
try {
|
||||
final Map<Class<?>, Method> methodMap = getMethodMap(enumClass);
|
||||
if (MapUtil.isNotEmpty(methodMap)) {
|
||||
final Class<?> valueClass = value.getClass();
|
||||
for (Map.Entry<Class<?>, Method> entry : methodMap.entrySet()) {
|
||||
if (ClassUtil.isAssignable(entry.getKey(), valueClass)) {
|
||||
return ReflectUtil.invokeStatic(entry.getValue(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
//oriInt 应该滞后使用 以 GB/T 2261.1-2003 性别编码为例,对应整数并非连续数字会导致数字转枚举时失败
|
||||
@ -98,17 +111,17 @@ public class EnumConverter extends AbstractConverter<Object> {
|
||||
//5 - 女性改(变)为男性
|
||||
//6 - 男性改(变)为女性
|
||||
//9 - 未说明的性别
|
||||
if (null == enumResult) {
|
||||
if (value instanceof Integer) {
|
||||
enumResult = EnumUtil.getEnumAt(enumClass, (Integer) value);
|
||||
} else if (value instanceof String) {
|
||||
try {
|
||||
enumResult = Enum.valueOf(enumClass, (String) value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
//ignore
|
||||
}
|
||||
Enum enumResult = null;
|
||||
if (value instanceof Integer) {
|
||||
enumResult = EnumUtil.getEnumAt(enumClass, (Integer) value);
|
||||
} else if (value instanceof String) {
|
||||
try {
|
||||
enumResult = Enum.valueOf(enumClass, (String) value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
return enumResult;
|
||||
}
|
||||
|
||||
@ -119,11 +132,11 @@ public class EnumConverter extends AbstractConverter<Object> {
|
||||
* @return 转换方法map,key为方法参数类型,value为方法
|
||||
*/
|
||||
private static Map<Class<?>, Method> getMethodMap(Class<?> enumClass) {
|
||||
return VALUE_OF_METHOD_CACHE.get(enumClass, ()-> Arrays.stream(enumClass.getMethods())
|
||||
return VALUE_OF_METHOD_CACHE.get(enumClass, () -> Arrays.stream(enumClass.getMethods())
|
||||
.filter(ModifierUtil::isStatic)
|
||||
.filter(m -> m.getReturnType() == enumClass)
|
||||
.filter(m -> m.getParameterCount() == 1)
|
||||
.filter(m -> false == "valueOf".equals(m.getName()))
|
||||
.collect(Collectors.toMap(m -> m.getParameterTypes()[0], m -> m)));
|
||||
.collect(Collectors.toMap(m -> m.getParameterTypes()[0], m -> m, (k1, k2) -> k1)));
|
||||
}
|
||||
}
|
||||
|
75
hutool-json/src/test/java/IssueI49VZBTest.java
Normal file
75
hutool-json/src/test/java/IssueI49VZBTest.java
Normal file
@ -0,0 +1,75 @@
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* https://gitee.com/dromara/hutool/issues/I49VZB
|
||||
*/
|
||||
public class IssueI49VZBTest {
|
||||
public enum NBCloudKeyType {
|
||||
/**
|
||||
* 指纹-视频云
|
||||
*/
|
||||
fingerPrint,
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
password,
|
||||
/**
|
||||
* 卡片
|
||||
*/
|
||||
card,
|
||||
/**
|
||||
* 临时密码
|
||||
*/
|
||||
snapKey;
|
||||
|
||||
public static NBCloudKeyType find(String value) {
|
||||
return Stream.of(values()).filter(e -> e.getValue().equalsIgnoreCase(value)).findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
public static NBCloudKeyType downFind(String keyType) {
|
||||
if (fingerPrint.name().equals(keyType.toLowerCase())) {
|
||||
return NBCloudKeyType.fingerPrint;
|
||||
} else {
|
||||
return find(keyType);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return super.toString().toLowerCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public static class UPOpendoor {
|
||||
|
||||
private String keyId;
|
||||
private NBCloudKeyType type;
|
||||
private String time;
|
||||
private int result;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBeanTest(){
|
||||
String str = "{type: \"password\"}";
|
||||
final UPOpendoor upOpendoor = JSONUtil.toBean(str, UPOpendoor.class);
|
||||
Assert.assertEquals(NBCloudKeyType.password, upOpendoor.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enumConvertTest(){
|
||||
final NBCloudKeyType type = Convert.toEnum(NBCloudKeyType.class, "snapKey");
|
||||
Assert.assertEquals(NBCloudKeyType.snapKey, type);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user