【Mybatis】mybatis-plus 通用枚举 @JsonValue 接收参数报错 No enum constant

2022-08-14 13:38:38

最近在使用mybatis-plus时用到了通用枚举,通过@JsonValue注解 向前端返回指定的字段,同时也可以接收前端返回的字段数据.

在这里插入图片描述
在使用@JsonValue时,确实可以做到数据库查询到数字自动转为文字返回给前端,但是前端想通过文字查询时,后端无法通过文字转为枚举对象,报出了No enum constant xxxx.enums.ProcessState.未处理

后来经过查阅,@JsonValue 走的是Jackson 进行的序列化 和反序列化, 在spring中 get请求(也就是requestParam) 是不经过Jackson 进行反序列化的,所以后端无法正常接收如果使用post(通过请求体传参 经过jackson反序列化)后端是可以正常接收到的.

通过查看spring源码,spring默认只能通过枚举实例名 转换为枚举实例对象 (也就是上图中的UNTREATED,PROCESSING 字符串 转化为枚举对象) .
在这里插入图片描述

解决办法: 这就需要我们自己写一个转换器了, 下例中使用了hutool的工具类hutool-反射工具
hutool - 类型转换工具类

@SuppressWarnings({"rawtypes","unchecked"})publicclassEnumConverterimplementsConverterFactory<String,Enum<?>>{@Overridepublic<TextendsEnum<?>>Converter<String,T>getConverter(Class<T> targetType){returnnewStringToEnum<>(targetType);}privatestaticclassStringToEnum<TextendsEnum>implementsConverter<String,T>{privatefinalClass<T> enumType;publicStringToEnum(Class<T> enumType){this.enumType= enumType;}@Override@NullablepublicTconvert(String source){if(source.isEmpty()){// It's an empty enum identifier: reset the enum value to null.returnnull;}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);returngetEnumObj(enumType, name, convert);}}}returnnull;}/**
		 * 通过反射的方式 获取枚举实例对象
		 *
		 * @param clazz     枚举类型
		 * @param fieldName @JSONValue 所在的字段名
		 * @param source    前端传进来的值
		 * @return 对应的枚举实例
		 * @author jzw
		 * @since 2021/11/12 10:11
		 */privateTgetEnumObj(Class<T> 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;}}}returnnull;}}}

将转换器配置进去即可

@ConfigurationpublicclassMyWebMvcConfigureimplementsWebMvcConfigurer{@OverridepublicvoidaddFormatters(FormatterRegistry registry){
		registry.addConverterFactory(newEnumConverter());}}

做完上面两步 就完成了 快去试试吧!

  • 作者:鲸渔
  • 原文链接:https://blog.csdn.net/qq_39078783/article/details/121281626
    更新时间:2022-08-14 13:38:38