当前位置:网站首页>若枚举映射的值不存在,则不进行反序列化
若枚举映射的值不存在,则不进行反序列化
2022-07-31 10:56:00 【搏·梦】
1. 前言
- 在开发中会经常使用到枚举,而使用其的时候,可能会出现传的值并不在枚举定义的值中,则报错如下(无法转换):

- 出现这样子的原因就是对应的值并不存在枚举里面,从而无法进行正常的对象转换赋值,一般经常出现场景无非两个地方:
一、controller层接口被外部调用的时候;
二、mybatis查询结果出来反序列化的时候。 - 某天突发想法,为什么在反序列化的时候,没有传入的值并不在枚举映射的值时候,不报错,自动赋值为null呢?
2. 先说结论
在controller层接口接收参数的时候,是使用objectMapper进行反序列化的,而里面有个配置:
READ_UNKNOWN_ENUM_VALUES_AS_NULL,意思就是:获取到不认识的枚举值赋值为null,不报错;
在springboot中可在yml配置文件中写:spring: jackson: deserialization: READ_UNKNOWN_ENUM_VALUES_AS_NULL: true在mybatis查询到结果反序列的时候,可以使用mybatis的类型处理器TypeHandler,来做反序列化时候判断。
在配置文件中指定默认的枚举类型处理器:mybatis: configuration: default-enum-type-handler: com.example.csdn.enum_test.MyEnumTypeHandler// 自定义枚举处理器,继承mybatis自带的EnumTypeHandler,简化优化需写的代码 // @MappedTypes 的意思是用于指明该TypeHandler实现类能够处理的Java 类型的集合 // @MappedTypes({Enum.class})的意思是:只有是枚举类型的才会走下面的处理器 @MappedTypes({ Enum.class}) public class MyEnumTypeHandler<E extends Enum<E>> extends EnumTypeHandler<E> { // 枚举类型对应的class对象 private final Class<E> type; public MyEnumTypeHandler(Class<E> type) { super(type); this.type = type; } @Override public E getNullableResult(ResultSet rs, String columnName) throws SQLException { String s = rs.getString(columnName); // 取到枚举所有值 final Field[] declaredFields = type.getFields(); // 如果从库里面取到的值,存在枚举值中的一个 // 则 直接转枚举,否则,直接负责为null return Arrays.stream(declaredFields).anyMatch(field -> field.getName().equals(s)) ? Enum.valueOf(type, s) : null; } }解释一下: 真正有这种需求的人可以考虑使用上述方法,其他情况下不建议这样子操作,毕竟如果对方传个莫名其妙的东西,你也不知道对方到底传递什么非法内容,直接转null了,而且在controller层dto对象中定义枚举,也是一种校验,直接不符合规则,更早报错。
3. 代码验证
1. controller层接口遇到枚举映射值不存在情况
在配置文件中配置:
spring: jackson: deserialization: READ_UNKNOWN_ENUM_VALUES_AS_NULL: true代码:
@Data public class testDto { private String name; private test_enum pwd; } public enum test_enum { A, B, C, } @RestController public class EnumController { @PostMapping("/enum/test") public void test2(@RequestBody testDto testDto){ System.out.println(testDto); } }
2. mybatis中枚举映射值不存在
在不加自定义类型处理器的情况下:


在加入自定义处理器的情况下:
配置文件中配置:mybatis: configuration: default-enum-type-handler: com.example.csdn.enum_test.MyEnumTypeHandler@MappedTypes({ Enum.class}) public class MyEnumTypeHandler<E extends Enum<E>> extends EnumTypeHandler<E> { // 枚举类型对应的class对象 private final Class<E> type; public MyEnumTypeHandler(Class<E> type) { super(type); this.type = type; } @Override public E getNullableResult(ResultSet rs, String columnName) throws SQLException { String s = rs.getString(columnName); // 取到枚举所有值 final Field[] declaredFields = type.getFields(); // 如果从库里面取到的值,存在枚举值中的一个 // 则 直接转枚举,否则,直接负责为null return Arrays.stream(declaredFields).anyMatch(field -> field.getName().equals(s)) ? Enum.valueOf(type, s) : null; } }

边栏推荐
- 【LeetCode】118.杨辉三角
- Redis缓冲穿透和缓冲击穿工具类的封装
- 7 天学个Go,Go 结构体 + Go range 来学学
- 《MySQL高级篇》五、InnoDB数据存储结构
- Mybaits Frequently Asked Questions Explained
- Insertion and deletion of doubly linked list
- DC-7-vulnhub
- 准确率(Accuracy)、精度(Precision)、召回率(Recall)和 mAP 的图解
- SQL——左连接(Left join)、右连接(Right join)、内连接(Inner join)
- SQL study notes - REGEXP operator
猜你喜欢

C#之泛型、委托、事件及其使用

淀粉与纤维素

Android安全专题(三)JNI混淆

医院管理系统数据库,课程设计,SQLserver,纯代码设计

FCN中制作自己的数据集并进行训练

小程序如何使用订阅消息(PHP代码+小程序js代码)

透过开发抽奖小程序,体会创新与迭代

Sql optimization summary!detailed!(Required for the latest interview in 2021)

「MySQL」- 基础增删改查

In half a month, MySQL has been consolidated again, and a tens of thousands of words "super hard core" article has been sorted out!
随机推荐
出色的移动端用户验证
WSL2安装.NET 6
The principle of v-model
1161. 最大层内元素和 (二叉树的层序遍历)
SQLServer2019安装(Windows)
strings包详细文档+示例
Day113. Shangyitong: user authentication, Alibaba Cloud OSS, patient management
单点登录原理及实现方式
“带薪划水”偷刷阿里老哥的面经宝典,三次挑战字节,终成正果
Creation of doubly linked list
nodeJs--querystring模块
【LeetCode】73.矩阵置零
实现弹框组件
面试、工作中常用sql大全(建议收藏备用)
Hospital management system database, course design, SQLserver, pure code design
SQL——左连接(Left join)、右连接(Right join)、内连接(Inner join)
Insertion and deletion of doubly linked list
我们能做出来数据库吗?
DC-7-vulnhub
Find a Go job in 7 days, Conditional statements to learn in Gopher, loop statements, Part 3