SpringBoot傳參轉換枚舉

有時候,咱們傳參的時候,但願使用枚舉類來看成參數spring

public enum VipEnum {
HUANG(1, "黃鑽"),
HONG(2, "紅鑽");
private Integer id;
private String value;app

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

public Integer getId() {
return id;
}this

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.HUANGorm

@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
而後呢咱們就稍微實現一下ip

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

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


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); }}1234567891011而後來就能夠進行轉換了,須要轉換的枚舉實現基類接口就能夠啦,是否是棒棒的!!

相關文章
相關標籤/搜索