poroto3 坑 枚举_spring boot 枚举使用的坑

java 枚举的功能挺多,但是坑更多,使用的时候要注意。如下面这个枚举。

@Getter

@AllArgsConstructorpublic enum EnumExpenseType implementsBaseEnum {

小欢喜(1),

大欢喜(2);private final intvalue;

}

咋一看,没什么问题,但是具体使用过程中,总是会出问题。原因就是这个枚举没有按照从0开始索引,除此之外即使从0开始,中间有断的索引也会有问题。主要出现在以下方面:

1. 在controller的方法中,比如以这个枚举为参数,如下代码:

@RequestMapping("/**")publicString getRejectReasons(EnumExpenseType type) {return "";

}

前台传入的参数如果是type:1, 那它值应该是:小欢喜,实际上呢?

Caused by: java.lang.IllegalArgumentException: No enum constant com.**.EnumReasonType.1

at java.lang.Enum.valueOf(Enum.java:238) ~[?:1.8.0_111]

at org.springframework.core.convert.support.StringToEnumConverterFactory$StringToEnum.convert(StringToEnumConverterFactory.java:52) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]

at org.springframework.core.convert.support.StringToEnumConverterFactory$StringToEnum.convert(StringToEnumConverterFactory.java:38) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]

at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]

at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]

at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]

at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:129) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:693) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]

at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:124) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]

... 81 more

Failed to convert value of type 'java.lang.String' to required type 'com.**.EnumExpenseType';

nested exception is org.springframework.core.convert.ConversionFailedException:

Failed to convert from type [java.lang.String] to type [com.**.EnumExpenseType] for value '1';

nested exception is java.lang.IllegalArgumentException: No enum constant com.***.EnumExpenseType.1

实际上它却报了个错。转换失败了。

查看报错信息,可以定位到是spring框架中StringToEnumConverterFactory中转换失败,具体代码如下:

private static class StringToEnum implements Converter{private final ClassenumType;public StringToEnum(ClassenumType) {this.enumType =enumType;

}

@OverridepublicT convert(String source) {if(source.isEmpty()) {//It's an empty enum identifier: reset the enum value to null.

return null;

}return (T) Enum.valueOf(this.enumType, source.trim());

}

}

是Enum.valueOf这里报错,Enum.valueOf的后面的值并不是我们的value,而是name(这里的小欢喜)。

所以,我们不能使用这个spring提供converter,需要自定义一个:StringToEnumConverterFactory

public class StringToEnumConverterFactory implements ConverterFactory{private static final Map converterMap = new HashMap<>();

@Overridepublic Converter getConverter(ClasstargetType) {

Converter converter =converterMap.get(targetType);if(converter == null) {

converter= new StringToEnumConverter<>(targetType);

converterMap.put(targetType, converter);

}returnconverter;

}class StringToEnumConverter implements Converter{private Map enumMap = new HashMap<>();

StringToEnumConverter(ClassenumType) {

T[] enums=enumType.getEnumConstants();for(T e : enums) {

enumMap.put(String.valueOf(e.getValue()), e);

}

}

@OverridepublicT convert(String source) {

T t=enumMap.get(source);if (t == null) {//异常可以稍后去捕获

throw new IllegalArgumentException("No element matches " +source);

}returnt;

}

}

}

然后再将这个工厂配置到项目中WebMvcConfigurationSupport:

@Overridepublic voidaddFormatters(FormatterRegistry registry) {

registry.addConverterFactory(newStringToEnumConverterFactory());

}

意思就是string 转 BaesEnum都走这个converter。

至此这个坑就算解决了。

下一篇继续...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值