有时候,我们传参的时候,希望使用枚举类来当作参数

public enum VipEnum {
HUANG(1, "黄钻"),
HONG(2, "红钻");
private Integer id;
private String value;

VipEnum(Integer id, String value) {
this.id = id;
this.value = value;
}

public Integer getId() {
return id;
}

public String getValue() {
return value;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
我们期望的是这样,参数中传一个1 后台就自动转换为枚举类的VipEnum.HUANG

@PostMapping("/vip")
public VipEnum convert(VipEnum vipEnum) {
return vipEnum;
}

1
2
3
4
5
实现Converter接口
这时候该怎么办呢?我们开始分析,是不是可以用到spring的类型转换器呢? spring为我们提供了一个类型自动转换接口Converter<S, T>,可以实现从一个Object转为另一个Object的功能。除了Converter接口之外

public interface Converter<S, T> {
T convert(S source);
}
1
2
3
然后呢我们就稍微实现一下

@Component
@Slf4j
public class PersonConverter implements Converter<String, VipEnum> {

@Override
public VipEnum convert(String value) {
log.info("参数是: {}", value);
return (VipEnum) PersonConverter.getEnum(VipEnum.class, value);
}

public static <T extends VipEnum> Object getEnum(Class<T> targerType, String source) {
for (T enumObj : targerType.getEnumConstants()) {
if (source.equals(String.valueOf(enumObj.getId()))) {
return enumObj;
}
}
return null;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这样呢就实现了转换,需要注意啊 在Spring MVC和Spring Boot中,由于从客户端接收到的请求都被视为String类型,所以只能用String转枚举的converter。

ConverterFactory接口
ConverterFactory的出现可以让我们统一管理一些相关联的Converter。顾名思义,ConverterFactory就是产生Converter的一个工厂,确实ConverterFactory就是用来产生Converter的。我们先来看一下ConverterFactory接口的定义

public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
1
2
3
可以看出 总共有 三个泛型S、R、T,其中

S表示原类型
R表示目标类型
T是类型R的一个子类
ConverterFactory相比converter的好处在于ConverterFactory可以将原类型转换成一组实现了相同接口类型的对象,而Converter则只能转换成一种类型,总不能一个枚举去实现一个Converter啊,这样肯定不行的。有了ConverterFactory之后,事情就变得简单了不少!

首先弄个基类接口

public interface IEnum<T> {
T getId();
}
1
2
3
然后让枚举类实现它

public enum VipEnum implements IEnum<Integer> {
HUANG(1, "黄钻"),
HONG(2, "红钻");
private Integer id;
private String value;

VipEnum(Integer id, String value) {
this.id = id;
this.value = value;
}

@Override
public Integer getId() {
return id;
}

public String getValue() {
return value;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
然后创建一个枚举工厂转换类

@Component
public class EnumConvertFactory implements ConverterFactory<String, IEnum> {
@Override
public <T extends IEnum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToIEum<>(targetType);
}

@SuppressWarnings("all")
private static class StringToIEum<T extends IEnum> implements Converter<String, T> {
private Class<T> targerType;
public StringToIEum(Class<T> targerType) {
this.targerType = targerType;
}

@Override
public T convert(String source) {
if (StringUtils.isEmpty(source)) {
return null;
}
return (T) EnumConvertFactory.getIEnum(this.targerType, source);
}
}

public static <T extends IEnum> Object getIEnum(Class<T> targerType, String source) {
for (T enumObj : targerType.getEnumConstants()) {
if (source.equals(String.valueOf(enumObj.getId()))) {
return enumObj;
}
}
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
这样还不行,紧接着,需要把转换工厂注入spring容器,这里呢我使用的是springbooot2.x

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Autowired
private EnumConvertFactory enumConvertFactory;

@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(enumConvertFactory);
}
}
1
2
3
4
5
6
7
8
9
10
11
然后来就可以进行转换了,需要转换的枚举实现基类接口就可以啦,是不是棒棒的!!

SpringBoot传参转换枚举的更多相关文章

  1. SpringBoot传参方式

    地址传参 1.创建一个Action类 package com.lion.action; import org.springframework.stereotype.Controller; import ...

  2. C# WebApi 根据实体类检查传参或字典检查参数

    根据实体类或字典检查传参,是否缺少参数并返回缺少参数 值类型必须声明可空 /// <summary> /// 根据 Dictionary<string, string> 得到实 ...

  3. SpringBoot 处理 POST Json 传参枚举

    在 Spring 框架中对枚举类型的序列化/反序列化是有限制的. 假设如下面这样在某些情况下就不能正常工作: 123456789 public enum PayChannelEnum implemen ...

  4. 枚举|标志枚举+|(或)和&(与)运算|类型转换|值类型和引用类型|传参|异常|垃圾回收

    枚举部分 enum 关键字用于声明枚举,即一种由一组称为枚举数列表的命名常量组成的独特类型. 通常情况下,最好是在命名空间内直接定义枚举,以便该命名空间中的所有类都能够同样方便地访问它. 但是,还可以 ...

  5. springboot对传参的拦截统一处理

    在学习某网<java秒杀系统方案优化>的课程中,学到了一种springboot对传参的拦截统一处理的方式,特记录一下. 如后台方法一般需要根据token从Session中获取User对象, ...

  6. SpringBoot系列: Java应用程序传参和SpringBoot参数文件

    ===========================向java 程序传参的几种形式:===========================1. 使用 OS 环境变量. 这个不推荐. 2. 使用JVM ...

  7. springboot实现xml传参和返回值

    1.新建maven工程xml-bean-convert pom.xml如下 <?xml version="1.0" encoding="UTF-8"?&g ...

  8. SpringBoot 2.x (2):请求和传参

    其实请求和传参这些知识属于SpringMVC 不过这也属于必须掌握的知识,巩固基础吧 GET请求: 以第一篇文章自动的方式创建SpringBoot项目: 然后新建Controller: package ...

  9. (day67)组件、组件化、组件传参、JS补充(命名转换、for in 、数据转换)、css取消选中和模拟小手

    目录 一.初识组件 (一)概念 (二)特点 二.组件的分类 (一)根组件 (二)局部组件 (三)全局组件 二.数据组件化 三.组件的传参 (一)父传子 (二)子传父 四.JS补充 (一)与html命名 ...

随机推荐

  1. YTU 2875: 倒霉蛋买饭去

    2875: 倒霉蛋买饭去 时间限制: 1 Sec  内存限制: 128 MB 提交: 22  解决: 17 题目描述 早春星期天的某个早晨,大风呼呼地刮.一个宿舍n个人,谁也不想起床买饭去.他们定了一 ...

  2. Ubuntu midi 播放

    One of the simplest methods to play a midi file in Ubuntu is to install timidity. sudo apt-get insta ...

  3. 【141】Adobe Acrobat技巧

    目录: 去除PDF的水印 待定 待定 待定 待定 待定 待定 待定 1. 批量去除PDF文件的水印 用Adobe Acrobat打开PDF文件之后,右侧选择工具>页面>水印>删除,可 ...

  4. 【转载】Java方向如何准备BAT技术面试答案(汇总版)

    作者:微信公众号JavaQ链接:https://www.nowcoder.com/discuss/31667?type=0&order=0&pos=11&page=1来源:牛客 ...

  5. Linux 系统管理命令 - free - 查看系统内存信息

    命令详解 重要星级: ★★★★★ 功能说明: free 命令用于显示系统内存状态,具体包括系统物理内存.虚拟内存.共享内存和系统缓存等. 语法格式: free [option] free [选项] 说 ...

  6. MySQL基础 -- 关系代数

    MySQL基础 -- 关系代数 关系代数是一种抽象的查询语言,它用对关系的运算来表达查询.  任何一种运算都是将一定的运算符作用于一定的运算对象上,得到预期的结果.所以运算对象.运算符.运算结果是运算 ...

  7. Luogu P1073 最优贸易【最短路/建反图】 By cellur925

    题目传送门 这么经典的题目,还是看了lyd的题解....唉难过. 一句话题意:在一张点有全都的图上找一条从1到n的路径,存在两个点p,q(p<q),使val[q]-val[p]最大. 给出的图是 ...

  8. [Usaco2006 Open]County Fair Events 参加节日庆祝

    Description Farmer John has returned to the County Fair so he can attend the special events (concert ...

  9. Frequency of String CodeForces - 963D

    http://codeforces.com/contest/963/problem/D 题解:https://www.cnblogs.com/Blue233333/p/8881614.html 记M为 ...

  10. 贪心 Codeforces Round #173 (Div. 2) B. Painting Eggs

    题目传送门 /* 题意:给出一种方案使得abs (A - G) <= 500,否则输出-1 贪心:每次选取使他们相差最小的,然而并没有-1:) */ #include <cstdio> ...