当前位置: 首页 > news >正文

SpringMVC枚举类型字段处理

在日常的项目开发中经常会遇到一些取值范围固定的字段,例如性别、证件类型、会员等级等,此时我们可以利用枚举来最大程度减少字段的乱定义,统一管理枚举的值。

SpringMVC中对于枚举也有默认的处理策略:

  • 对于@RequestParam,Spring是通过ConverterFactory来处理的,大致处理策略是根据枚举名称或枚举下标来转换枚举。
    在这里插入图片描述

  • 对于@RequestBody,Spring是通过Jackson配置将json内的枚举值转换为对象的,大致处理策略同样是根据枚举名称或枚举下标来转换枚举。

在SpringMVC内对枚举的默认处理逻辑是根据枚举的类名或枚举下标来将请求参数转化为枚举对象,这显然不太灵活,因此我们需要调整枚举字段的处理逻辑。

RequestParam处理

我们可以自定义ConvertFactory来自定义枚举字段的转化策略。

  1. 定义BaseEnum接口,规定所有枚举都应该实现此接口

    public interface BaseEnum<T> {/*** 获取枚举值*/T getCode();/*** 根据值获取对应的枚举* @param enumTypeClazz 枚举类型类* @param value 值*/static <T extends BaseEnum> T getEnumByCode(Class<T> enumTypeClazz, Object value) {if (enumTypeClazz == null || value == null) {return null;}Optional<T> optional = Arrays.stream(enumTypeClazz.getEnumConstants()).filter(e ->{Object enumCode = e.getCode();return Objects.equals(Convert.convert(enumCode.getClass(), value),enumCode);}).findFirst();//如果不存在则抛异常return optional.orElseThrow( ()-> new RuntimeException("[" + enumTypeClazz.getSimpleName() + "]参数错误[" + value + "]"));}
    }
  2. 自定义ConverterFactory

    @Component
    public class EnumConverterFactory implements ConverterFactory<String, BaseEnum> {@Overridepublic <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) {return source -> BaseEnum.getEnumByCode(targetType, source);}
    }
    
  3. 注册ConverterFactory

    @Configuration
    public class SpringMVCConfig implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverterFactory(new EnumConverterFactory());}}
    
  4. 这样配置后请求参数就会自动转换为枚举了。

    //枚举类
    @AllArgsConstructor
    @Getter
    public enum Gender implements BaseEnum<Integer> {MALE(1,"男"),FEMALE(2,"女"),;@EnumValueprivate Integer code;private String value;}//通过接口接受gender参数,能够根据code自动转换为对应的枚举
    @GetMapping("/test")
    public Gender insert(Gender gender) {return gender;
    }
    

RequestBody处理

RequestBody是通过Jackson转换对请求参数进行处理的,因此我们只需要自定义反序列化类即可

  1. 自定义序列化规则设置json内的值如何转换为枚举

    public class EnumDeserializer extends JsonDeserializer<BaseEnum> {/*** 根据参数值获取对应的枚举* @throws IOException* @throws JacksonException*/@Overridepublic BaseEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {// 当前值final String paramValue = p.getText();//获取序列化信息final JsonStreamContext parsingContext = p.getParsingContext();// 获取当前序列化的类的对象final Object currentValue = parsingContext.getCurrentValue();//获取当前序列化的字段名final String currentName = parsingContext.getCurrentName();try {// 反射获取当前序列化字段信息final Field declaredField = currentValue.getClass().getDeclaredField(currentName);// 通过字段信息获取对应的枚举的Classfinal Class<BaseEnum> targetType = (Class<BaseEnum>) declaredField.getType();//根据参数值获取对应的枚举BaseEnum baseEnum = BaseEnum.getEnumByCode(targetType, paramValue);if (ObjectUtil.isEmpty(baseEnum)) {throw new RuntimeException("[" + currentName + "]参数错误");}//返回枚举return baseEnum;} catch (NoSuchFieldException e) {throw new RuntimeException("[" + currentName + "]参数错误");}}}
    
    1. 在枚举类加上 @JsonDeserialize(using = EnumDeserializer.class)
       //可以直接加到刚刚定义的BaseEnum接口上,这样所有枚举就自动继承了@JsonDeserialize(using = EnumDeserializer.class)public interface BaseEnum<T> {……}
    
    1. 这样配置后@RequestBody就能够自动转换枚举了
    @PostMapping("/save")
    public User save(@RequestBody User user) {studentService.save(user);return user;
    }
    

枚举字段返回序列化

如果我们返回的对象内有枚举字段,SpringMVC会默认将枚举的名称作为值返回,如果我们想指定枚举类的某个属性作为值,可以通过@JsonValue指定

@AllArgsConstructor
@Getter
public enum Gender implements BaseEnum<Integer> {MALE(1,"男"),FEMALE(2,"女"),;//指定转json时使用code作为值@JsonValueprivate Integer code;private String value;}

或者直接在枚举类上加@JsonFormat,将枚举转换为对象格式

@JsonFormat(shape= JsonFormat.Shape.OBJECT)
@JsonDeserialize(using = EnumDeserializer.class)
public interface BaseEnum<T> {……
}

MybatisPlus对枚举的处理

MybatisPlus直接在枚举类的属性上加@EnumValue即可,并且兼容xml内的动态sql

@AllArgsConstructor
@Getter
public enum Gender implements BaseEnum<Integer> {MALE(1,"男"),FEMALE(2,"女"),;//指定code作为入库时的值@EnumValueprivate Integer code;private String value;}

相关文章:

SpringMVC枚举类型字段处理

在日常的项目开发中经常会遇到一些取值范围固定的字段&#xff0c;例如性别、证件类型、会员等级等&#xff0c;此时我们可以利用枚举来最大程度减少字段的乱定义&#xff0c;统一管理枚举的值。 SpringMVC中对于枚举也有默认的处理策略&#xff1a; 对于RequestParam&#xf…...

集成算法:Bagging模型、AdaBoost模型和Stacking模型

概述 目的&#xff1a;让机器学习效果更好&#xff0c;单个不行&#xff0c;集成多个 集成算法 Bagging&#xff1a;训练多个分类器取平均 f ( x ) 1 / M ∑ m 1 M f m ( x ) f(x)1/M\sum^M_{m1}{f_m(x)} f(x)1/M∑m1M​fm​(x) Boosting&#xff1a;从弱学习器开始加强&am…...

DW怎么Python:探索Dreamweaver与Python的交织世界

DW怎么Python&#xff1a;探索Dreamweaver与Python的交织世界 在数字世界的广袤天地中&#xff0c;Dreamweaver&#xff08;简称DW&#xff09;与Python这两大工具各自闪耀着独特的光芒。DW以其强大的网页设计和开发能力著称&#xff0c;而Python则以其简洁、易读和强大的编程…...

算法(十三)回溯算法---N皇后问题

文章目录 算法概念经典例子 - N皇后问题什么是N皇后问题&#xff1f;实现思路 算法概念 回溯算法是类似枚举的深度优先搜索尝试过程&#xff0c;主要是再搜索尝试中寻找问题的解&#xff0c;当发生不满足求解条件时&#xff0c;就会”回溯“返回&#xff08;也就是递归返回&am…...

论文阅读:Correcting Motion Distortion for LIDAR HD-Map Localization

目录 概要 Motivation 整体架构流程 技术细节 小结 论文地址&#xff1a;http://arxiv.org/pdf/2308.13694.pdf 代码地址&#xff1a;https://github.com/mcdermatt/VICET 概要 激光雷达的畸变矫正是一个非常重要的工作。由于扫描式激光雷达传感器需要有限的时间来创建…...

Git操作笔记

学git已经好多次了。但是还是会忘记很多的东西&#xff0c;一些常用的操作命令和遇到的bug以后在这边记录汇总下 一.github图片展示 图片挂载&#xff0c;我是创建了一个库专门存图片&#xff0c;然后在github的md中用专用命令展示图片&#xff0c;这样你的md就不会全是文字那…...

使用Python进行数据分析的基本步骤

简介&#xff1a; 在当今的数据驱动世界中&#xff0c;数据分析已成为各行各业不可或缺的一部分。Python作为一种强大的编程语言&#xff0c;提供了丰富的库和工具&#xff0c;使得数据分析变得简单易行。本文将带你了解使用Python进行数据分析的基本步骤。 一、数据获取 从外…...

NGINX优化

NGINX优化分为两个方面&#xff1a; 一. nginx应用配置文件的优化&#xff1a; 1.nginx的性能优化: 全局块&#xff1a; 设置工作进程数&#xff1a; work_processes #设置工作进程数 设置工作进程连接数&#xff1a;work_rilmit_nofile #设置每个worker进程最大可…...

【LeetCode刷题】二分查找:山脉数组的峰顶索引、寻找峰值

【LeetCode刷题】Day 13 题目1&#xff1a;852.山脉数组的峰顶索引思路分析&#xff1a;思路1&#xff1a;暴力枚举O(N)思路2&#xff1a;二分查找O(logN) 题目2&#xff1a;162.寻找峰值思路分析&#xff1a;思路1&#xff1a;二分查找O(logN) 题目1&#xff1a;852.山脉数组的…...

《Python学习》-- 实操篇一

一、文件操作 1. 1 读取文本文件 # 文件操作模式 # r (默认) - 只读模式。文件必须存在&#xff0c;否则会抛出FileNotFoundError。在这种模式下&#xff0c;你只能读取文件内容&#xff0c;不能写入或追加。 # w - 写入模式。如果文件存在&#xff0c;内容会被清空&#xff…...

C# 集合(二) —— List/Queue类

总目录 C# 语法总目录 集合二 List/Queue 1. List2. Queue 1. List List有ArrayList和LinkedList ArrayList 类似数组&#xff0c;查找快&#xff0c;插入删除慢(相对)LinkedList 类似双向链表&#xff0c;查找慢(相对)&#xff0c;插入删除快 //ArrayList //ArrayList Arr…...

【TB作品】MSP430 G2553 单片机口袋板,读取单片机P1.4电压显示,ADC

功能 读取P1.4电压&#xff0c;显示到口袋板显示屏&#xff0c;电压越高亮灯越多。 部分程序 while (1){ADC10CTL0 | ENC ADC10SC; // Sampling and conversion startLPM0;adcvalue ADC10MEM; //原始数据 0到1023adtest (float) adcvalue / 1024.…...

知乎x-zse-96、x-zse-81

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…...

【Linux】Linux工具——yum,vim

1.Linux 软件包管理器——yum Linux安装软件&#xff1a; 源代码安装&#xff08;不建议&#xff09;rpm安装&#xff08;类似Linux安装包&#xff0c;版本可能不兼容&#xff0c;不推荐&#xff0c;容易报错&#xff09;yum安装&#xff08;解决了安装源&#xff0c;安装版本&…...

ES 生命周期管理

一 .概念 ILM定义了四个生命周期阶段&#xff1a;Hot&#xff1a;正在积极地更新和查询索引。Warm&#xff1a;不再更新索引&#xff0c;但仍在查询。cold&#xff1a;不再更新索引&#xff0c;很少查询。信息仍然需要可搜索&#xff0c;但是如果这些查询速度较慢也可以。Dele…...

【JavaScript脚本宇宙】揭秘HTTP请求库:深入理解它们的特性与应用

深度揭秘&#xff1a;六大HTTP请求库的比较与应用 前言 在这篇文章中&#xff0c;我们将探讨六种主要的HTTP请求库。这些库为处理网络请求提供了不同的工具和功能&#xff0c;包括Axios、Fetch API、Request、SuperAgent、Got和Node-fetch。通过本文&#xff0c;你将对每个库…...

【强化学习】DPO(Direct Preference Optimization)算法学习笔记

【强化学习】DPO&#xff08;Direct Preference Optimization&#xff09;算法学习笔记 RLHF与DPO的关系KL散度Bradley-Terry模型DPO算法流程参考文献 RLHF与DPO的关系 DPO&#xff08;Direct Preference Optimization&#xff09;和RLHF&#xff08;Reinforcement Learning f…...

vue3 todolist 简单例子

vue3 简单的TodList 地址&#xff1a; https://gitee.com/cheng_yong_xu/vue3-composition-api-todo-app-my 效果 step-1 初始化项项目 我们不采用vue cli 搭建项目 直接将上图文件夹&#xff0c;复制到vscode编辑器&#xff0c;清空App.vue的内容 安装包 # 安装包 npm…...

Linux项目编程必备武器!

本文目录 一、更换源服务器二、下载man开发手册(一般都自带&#xff0c;没有的话使用下面方法下载) 一、更换源服务器 我们使用apt-get等下载命令下载的软件都是从源服务器上获取的&#xff0c;有些软件包在某个服务器上存在&#xff0c;而另一个服务器不存在。所以我们可以添加…...

AndroidStudio编译很慢问题解决

如果gradle同步、编译下载很慢&#xff0c;可以换一下仓库阿里云镜像 repositories {maven { url https://maven.aliyun.com/repository/google } maven { url https://maven.aliyun.com/repository/jcenter } maven { url https://maven.aliyun.com/repository/public } goog…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...