有时候,我们传参的时候,希望使用枚举类来当作参数
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 后台就自动转换为枚举类的VipEnum.HUANG
@PostMapping("/vip") public VipEnum convert(VipEnum vipEnum) { return vipEnum; }
这时候该怎么办呢?我们开始分析,是不是可以用到spring的类型转换器呢? spring为我们提供了一个类型自动转换接口Converter<S, T>,可以实现从一个Object转为另一个Object的功能。除了Converter接口之外
public interface Converter<S, T> { T convert(S source); }
然后呢我们就稍微实现一下
@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; } }
这样呢就实现了转换,需要注意啊 在Spring MVC和Spring Boot中,由于从客户端接收到的请求都被视为String类型,所以只能用String转枚举的converter。
ConverterFactory的出现可以让我们统一管理一些相关联的Converter。顾名思义,ConverterFactory就是产生Converter的一个工厂,确实ConverterFactory就是用来产生Converter的。我们先来看一下ConverterFactory接口的定义
public interface ConverterFactory<S, R> { <T extends R> Converter<S, T> getConverter(Class<T> targetType); }
可以看出 总共有 三个泛型S、R、T,其中
ConverterFactory相比converter的好处在于ConverterFactory可以将原类型转换成一组实现了相同接口类型的对象,而Converter则只能转换成一种类型,总不能一个枚举去实现一个Converter啊,这样肯定不行的。有了ConverterFactory之后,事情就变得简单了不少!
首先弄个基类接口
public interface IEnum<T> { T getId(); }
然后让枚举类实现它
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; } }
然后创建一个枚举工厂转换类
@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; } }
这样还不行,紧接着,需要把转换工厂注入spring容器,这里呢我使用的是springbooot2.x
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private EnumConvertFactory enumConvertFactory; @Override public void addFormatters(FormatterRegistry registry) { registry.addConverterFactory(enumConvertFactory); } }
然后来就可以进行转换了,需要转换的枚举实现基类接口就可以啦,是不是棒棒的!!
有时候,我们传参的时候,希望使用枚举类来当作参数
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 后台就自动转换为枚举类的VipEnum.HUANG
@PostMapping("/vip")
public VipEnum convert(VipEnum vipEnum) {
return vipEnum;
}
这时候该怎么办呢?我们开始分析,是不是可以用到spring的类型转换器呢? spring为我们提供了一个类型自动转换接口Converter<S, T>,可以实现从一个Object转为另一个Object的功能。除了Converter接口之外
public interface Converter<S, T> {
T convert(S source);
}
然后呢我们就稍微实现一下
@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;
}
}
这样呢就实现了转换,需要注意啊 在Spring MVC和Spring Boot中,由于从客户端接收到的请求都被视为String类型,所以只能用String转枚举的converter。
ConverterFactory的出现可以让我们统一管理一些相关联的Converter。顾名思义,ConverterFactory就是产生Converter的一个工厂,确实ConverterFactory就是用来产生Converter的。我们先来看一下ConverterFactory接口的定义
public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
可以看出 总共有 三个泛型S、R、T,其中
ConverterFactory相比converter的好处在于ConverterFactory可以将原类型转换成一组实现了相同接口类型的对象,而Converter则只能转换成一种类型,总不能一个枚举去实现一个Converter啊,这样肯定不行的。有了ConverterFactory之后,事情就变得简单了不少!
首先弄个基类接口
public interface IEnum<T> {
T getId();
}
然后让枚举类实现它
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;
}
}
然后创建一个枚举工厂转换类
@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;
}
}
这样还不行,紧接着,需要把转换工厂注入spring容器,这里呢我使用的是springbooot2.x
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private EnumConvertFactory enumConvertFactory;
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(enumConvertFactory);
}
}
然后来就可以进行转换了,需要转换的枚举实现基类接口就可以啦,是不是棒棒的!!
原文:https://www.cnblogs.com/shxy-wlzx/p/14280360.html