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

 更新时间:2023年09月26日 09:14:28   作者:鲸渔  
最近在使用mybatis-plus时用到了通用枚举,遇到了问题,本文主要介绍了mybatis-plus通用枚举@JsonValue接收参数报错No enum constant,具有一定的参考价值,感兴趣的可以了解一下

最近在使用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"})
public class EnumConverter implements ConverterFactory<String, Enum<?>> {
	@Override
	public <T extends Enum<?>> Converter<String, T> getConverter(Class<T> targetType) {
		return new StringToEnum<>(targetType);
	}
	private static class StringToEnum<T extends Enum> implements Converter<String, T> {
		private final Class<T> enumType;
		public StringToEnum(Class<T> 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;
		}
		/**
		 * 通过反射的方式 获取枚举实例对象
		 *
		 * @param clazz     枚举类型
		 * @param fieldName @JSONValue 所在的字段名
		 * @param source    前端传进来的值
		 * @return 对应的枚举实例
		 * @author jzw
		 * @since 2021/11/12 10:11
		 */
		private T getEnumObj(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;
					}
				}
			}
			return null;
		}
	}
}

将转换器配置进去即可

@Configuration
public class MyWebMvcConfigure implements WebMvcConfigurer {
	@Override
	public void addFormatters(FormatterRegistry registry) {
		registry.addConverterFactory(new EnumConverter());
	}
}

做完上面两步 就完成了

到此这篇关于mybatis-plus通用枚举@JsonValue接收参数报错No enum constant的文章就介绍到这了,更多相关mybatis-plus @JsonValue参数报错内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现将Doc/Docx格式的Word文档转换为PDF文件

    Java实现将Doc/Docx格式的Word文档转换为PDF文件

    这篇文章主要为大家详细介绍了如何通过Java将Word文档转换为PDF、PDF/A和密码保护的PDF文件,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2025-08-08
  • Spring元注解@HttpExchange声明式调用HTTP

    Spring元注解@HttpExchange声明式调用HTTP

    这篇文章主要介绍了Spring元注解@HttpExchange声明式调用HTTP,Spring Framework6和Spring Boot3引入了声明式HTTP客户端@HttpExchange,通过接口注解简化REST API调用,核心注解包括@GetExchange、@PostExchange等对应HTTP方法,支持路径参数和请求体,需要的朋友可以参考下
    2025-10-10
  • 为什么Java是程序员受欢迎的语言这几个原因你该清楚

    为什么Java是程序员受欢迎的语言这几个原因你该清楚

    Java一直稳居程序员很受欢迎的编程语言的榜首,是企业中使用最广泛的编程语言。这篇文章主要介绍了为什么Java是程序员受欢迎的语言这几个原因你该清楚,需要的朋友可以参考下
    2020-07-07
  • springboot+redis+lua实现分布式锁的脚本

    springboot+redis+lua实现分布式锁的脚本

    本文介绍了如何使用Spring Boot、Redis和Lua脚本实现分布式锁,包括实现原理、代码实现和存在的问题,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • Spring Boot中使用Spring-data-jpa实现数据库增删查改

    Spring Boot中使用Spring-data-jpa实现数据库增删查改

    本篇文章主要介绍了Spring Boot中使用Spring-data-jpa实现增删查改,非常具有实用价值,需要的朋友可以参考下。
    2017-03-03
  • Mybatis-Plus中IdType.AUTO局部配置不生效的问题解决

    Mybatis-Plus中IdType.AUTO局部配置不生效的问题解决

    本文主要介绍了Mybatis-Plus中IdType.AUTO局部配置不生效的问题解决,数据库插入数据时,id的默认生成方式还是雪花算法,局部配置没有生效,下面就来解决一下,感兴趣的可以了解一下
    2023-09-09
  • JAVAEE Filter 过滤器设置是否缓存实例详解

    JAVAEE Filter 过滤器设置是否缓存实例详解

    网页中,每次的客户端访问服务器,有部分不用重复请求的,这样可以减轻服务器的工作量。那么如何设置客户端是否都缓存呢?接下来通过本文给大家介绍JAVAEE Filter 过滤器设置是否缓存的实例,感兴趣的朋友一起学习吧
    2016-05-05
  • springboot整合JSR303校验功能实现代码

    springboot整合JSR303校验功能实现代码

    这篇文章主要介绍了springboot整合JSR303校验功能实现,JSR303校验方法有统一校验的需求,统一校验实现以及分组校验,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • Java的非阻塞队列ConcurrentLinkedQueue解读

    Java的非阻塞队列ConcurrentLinkedQueue解读

    这篇文章主要介绍了Java的非阻塞队列ConcurrentLinkedQueue解读,在并发编程中,有时候需要使用线程安全的队列,如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法,需要的朋友可以参考下
    2023-12-12
  • Java如何去掉指定字符串的开头的指定字符

    Java如何去掉指定字符串的开头的指定字符

    这篇文章主要介绍了Java去掉指定字符串的开头的指定字符操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论