Hutool json 反序列化踩坑
String str = """
{
"datetime": 1758005950126,
"deviceId": {
"deviceNo": "019826710",
"productKey": "WA-206"
},
"executeResult": "SUCCESSFUL",
"paramResult": "GPSKG=1",
"paramResultMap": {
"LOCATION_FUNCTION": "1"
},
"receiptType": "EXECUTED",
"serialNo": 1967845697533378560
}
""";
CommandEventMessage message = JSONUtil.toBean(str, CommandEventMessage.class);
对于 paramResultMap 中的 key 枚举去自动调用了枚举类的成员方法
public static PropertyIdentifierEnum fromIdentifier(String identifier) {
PropertyIdentifierEnum result = IDENTIFIER_MAP.get(identifier);
if (result == null) {
log.warn("No enum constant with identifier: {}", identifier);
}
return result;
}
但是很明显这个方法并不是为反序列化准备的,于是报错
其原因确实简单粗暴且迷惑
protected static Enum tryConvertEnum(Object value, Class enumClass) {
if (value == null) {
return null;
}
// EnumItem实现转换
if (EnumItem.class.isAssignableFrom(enumClass)) {
final EnumItem first = (EnumItem) EnumUtil.getEnumAt(enumClass, 0);
if (null != first) {
if (value instanceof Integer) {
return (Enum) first.fromInt((Integer) value);
} else if (value instanceof String) {
return (Enum) first.fromStr(value.toString());
}
}
}
// 用户自定义方法
// 查找枚举中所有返回值为目标枚举对象的方法,如果发现方法参数匹配,就执行之
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
}