最近在使用mybatis-plus时用到了通用枚举,通过@JsonValue注解 向前端返回指定的字段,同时也可以接收前端返回的字段数据.
在使用@JsonValue时,确实可以做到 将文字返还给前端,但是前端做查询的时候,将文字发送后端时则出现了问题,报出了 No enum constant xxxx.enums.ProcessState.未处理
后来经过查阅,@JsonValue 走的是Jackson 进行的序列化 和反序列化, 大家都知道 get请求(也就是requestParam) 是不经过Jackson 进行反序列化的,所以后端无法正常接收如果使用post(通过请求体传参 经过jackson反序列化)后端是可以正常接收到的.
通过查看spring源码,spring默认只能通过枚举 实例名 转换为枚举 实例对象 (也就是上图中的 UNTREATED,PROCESSING 字符串 转化为枚举对象) .
解决办法: 这就需要我们自己写一个转换器了, 下例中使用了hutool的工具类hutool-反射工具
hutool - 类型转换工具类
@SuppressWarnings({"rawtypes", "unchecked"})
public class EnumConverter implements ConverterFactory> {
@Override
public > Converter getConverter(Class targetType) {
return new StringToEnum<>(targetType);
}
private static class StringToEnum implements Converter {
private final Class enumType;
public StringToEnum(Class enumType) {
this.enumType = enumType;
}
@Override
@Nullable
public T convert(String source) {
if (source.isEmpty()) {
// It's an empty enum identifier: reset the enum value to null.
return null;
}
try {
//先通过name获取枚举
return (T) Enum.valueOf(enumType, source);
} catch (Exception e) {
Field[] declaredFields = enumType.getDeclaredFields();
for (Field declaredField : declaredFields) {
JsonValue[] annotationsByType = declaredField.getAnnotationsByType(JsonValue.class);
if (annotationsByType.length > 0) {
String name = declaredField.getName();
Object convert = Convert.convert(declaredField.getType(), source);
return getEnumObj(enumType, name, convert);
}
}
}
return null;
}
private T getEnumObj(Class clazz, String fieldName, Object source) {
T[] enums = clazz.getEnumConstants();
if (null != enums) {
for (T e : enums) {
Object fieldValue = ReflectUtil.getFieldValue(e, fieldName);
if (fieldValue.equals(source)) {
return e;
}
}
}
return null;
}
}
}
将转换器配置进去即可
@Configuration
public class MyWebMvcConfigure implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new EnumConverter());
}
}
做完上面两步 就完成了 快去试试吧!



