Spring Boot中枚举使用常见问题汇总有哪些?

2026-06-10 16:221阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计925个文字,预计阅读时间需要4分钟。

Spring Boot中枚举使用常见问题汇总有哪些?

Java中枚举的泛用性较强,但实现时需注意性能问题,使用时需谨慎。以下是一个简化版的枚举示例:

java@Getter @AllArgsConstructorpublic enum EnumExpenseType implements BaseEnum { SMALL_ENJOYMENT(1), BIG_ENJOYMENT(2);

private final int value;}

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

@Getter @AllArgsConstructor public enum EnumExpenseType implements BaseEnum { 小欢喜(1), 大欢喜(2); private final int value; }

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

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

@RequestMapping("/**") public String 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<T extends Enum> implements Converter<String, T> { private final Class<T> enumType; public StringToEnum(Class<T> enumType) { this.enumType = enumType; } @Override public T 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<String, BaseEnum> { private static final Map<Class, Converter> converterMap = new HashMap<>(); @Override public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) { Converter<String, T> converter = converterMap.get(targetType); if(converter == null) { converter = new StringToEnumConverter<>(targetType); converterMap.put(targetType, converter); } return converter; } class StringToEnumConverter<T extends BaseEnum> implements Converter<String, T> { private Map<String, T> enumMap = new HashMap<>(); StringToEnumConverter(Class<T> enumType) { T[] enums = enumType.getEnumConstants(); for(T e : enums) { enumMap.put(String.valueOf(e.getValue()), e); } } @Override public T convert(String source) { T t = enumMap.get(source); if (t == null) { // 异常可以稍后去捕获 throw new IllegalArgumentException("No element matches " + source); } return t; } } }

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

@Override public void addFormatters(FormatterRegistry registry) { registry.addConverterFactory(new StringToEnumConverterFactory()); }

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

Spring Boot中枚举使用常见问题汇总有哪些?

至此这个坑就算解决了。

以上就是本次介绍的全部知识点内容,感谢大家对自由互联的支持。

标签:整理Java

本文共计925个文字,预计阅读时间需要4分钟。

Spring Boot中枚举使用常见问题汇总有哪些?

Java中枚举的泛用性较强,但实现时需注意性能问题,使用时需谨慎。以下是一个简化版的枚举示例:

java@Getter @AllArgsConstructorpublic enum EnumExpenseType implements BaseEnum { SMALL_ENJOYMENT(1), BIG_ENJOYMENT(2);

private final int value;}

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

@Getter @AllArgsConstructor public enum EnumExpenseType implements BaseEnum { 小欢喜(1), 大欢喜(2); private final int value; }

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

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

@RequestMapping("/**") public String 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<T extends Enum> implements Converter<String, T> { private final Class<T> enumType; public StringToEnum(Class<T> enumType) { this.enumType = enumType; } @Override public T 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<String, BaseEnum> { private static final Map<Class, Converter> converterMap = new HashMap<>(); @Override public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) { Converter<String, T> converter = converterMap.get(targetType); if(converter == null) { converter = new StringToEnumConverter<>(targetType); converterMap.put(targetType, converter); } return converter; } class StringToEnumConverter<T extends BaseEnum> implements Converter<String, T> { private Map<String, T> enumMap = new HashMap<>(); StringToEnumConverter(Class<T> enumType) { T[] enums = enumType.getEnumConstants(); for(T e : enums) { enumMap.put(String.valueOf(e.getValue()), e); } } @Override public T convert(String source) { T t = enumMap.get(source); if (t == null) { // 异常可以稍后去捕获 throw new IllegalArgumentException("No element matches " + source); } return t; } } }

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

@Override public void addFormatters(FormatterRegistry registry) { registry.addConverterFactory(new StringToEnumConverterFactory()); }

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

Spring Boot中枚举使用常见问题汇总有哪些?

至此这个坑就算解决了。

以上就是本次介绍的全部知识点内容,感谢大家对自由互联的支持。

标签:整理Java