SpringBoot使用枚举类型作为请求参数
1. 场景
在controller 接收 包含有枚举类属性的类的时候,只能根据枚举类的成员名称去进行获取,不能根据成员变量去进行获取。根据成员变量是找不到对应的枚举成员
- 正常情况
1 | // 枚举类 |
2. 需求
能根据枚举值的成员变量去进行获取对应的枚举成员而不是必须根据成员名去获取对应的成员
大致思路方向:
- 根据Spring提供的转换器去进行转换
3. 实现之Spring转换器
3.1 初步实现
1 | /** |
3.2 通用实现
具体的实现思路是利用接口的向下转型
优点:
- 如果用上一种方式,假如需要转换的枚举类型有很多那么将会写很多的转换类
缺点:
- 成员变量名必须是value和name不然转换不会成功,需要转换的都必须实现NameValueEnum接口类
注意点:name和value是不能值一样的不然会出现歧义,在获取的过程中可能会进行覆盖
定义两个接口
ValueEnum.java和NameValueEnum.javaValueEnum.java1
2
3
4
5
6
7
8public interface ValueEnum<T> {
/**
* 获取枚举值
*
* @return 枚举值
*/
T getValue();
}NameValueEnum.java1
2
3
4
5
6
7
8public interface NameValueEnum<T> extends ValueEnum<T>{
/**
* 获取枚举名称
*
* @return 枚举名
*/
String getName();
}所有需要转换的枚举需要实现这两个接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 枚举类 因为使用了lomok 所有并不会报错
public enum LoginType implements NameValueEnum<String> implements NameValueEnum{
MOBILE_CODE_LOGIN("0", "手机验证码登录"),
;
// 名称
private final String name;
// 值
private final String value;
LoginType(String value, String name) {
this.value = value;
this.name = name;
}
}定义
Converter .java和ConverterFactory.javaConverter .java
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
33
34
35public class NameValueToEnumConverter<T extends NameValueEnum> implements Converter<String, T> {
private Map<String, T> nameMap = new HashMap<>();
private Map<String, T> valueMap = new HashMap<>();
/**
* 根据enumType 去获取枚举里面的成员 并存入map中
*/
public NameValueToEnumConverter(Class<T> enumType) {
// getEnumConstants 获取枚举成员 如果不是枚举返回null
Arrays.stream(enumType.getEnumConstants())
.forEach(o->{
nameMap.put(o.getName(),o);
valueMap.put(o.getValue().toString(),o);
});
}
/**
*
* @param source 传进controller的枚举字符串
* @return
*/
public T convert(String source) {
T value = valueMap.get(source);
if (!ObjectUtil.isNull(value)) {
return value;
}
T name = nameMap.get(source);
if (!ObjectUtil.isNull(name)) {
return name;
}
throw new BizException(ResultCode.ENUM_PARAMS_NOT_MATCH);
}
}
}ConverterFactory.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class NameValueToEnumConverterFactory implements ConverterFactory<String, NameValueEnum> {
// 存储转换器的缓存
private static final Map<Class, Converter> CONVERTERS = new HashMap<>();
/**
* 获取转换器的方法
* @param targetType 转换后的类型
* @return 返回一个转化器
*/
public <T extends NameValueEnum> Converter<String, T> getConverter(Class<T> targetType) {
// 从缓存中获取已存在的转换器
Converter<String, T> converter = CONVERTERS.get(targetType);
if (converter == null) {
// 如果缓存中不存在该类型的转换器,则创建一个新的转换器 防止重复添加
converter = new NameValueToEnumConverter<>(targetType);
// 将新创建的转换器添加到缓存中
CONVERTERS.put(targetType, converter);
}
return converter;
}
}
3.3 将转化器工厂添加进 Spring Boot 配置
1 |
|
3.4 测试
测试通过
1 | ### |
评论




