Java Spring-MVC枚举识别
在控制器中,我们希望使用枚举作为方法参数:Java Spring-MVC枚举识别,java,spring,spring-mvc,enums,Java,Spring,Spring Mvc,Enums,在控制器中,我们希望使用枚举作为方法参数: @GetMapping("/feed") public void feed(@RequestParam myEnum: MyEnum) 在我们尝试使用大小写不匹配的字符串之前,这是有效的。为此,我发现了一个类似的问题: 但是,这需要为每个枚举设置处理程序。我更愿意为所有枚举实现自定义处理程序。比如: val ordinal = param.toString().toIntOrNull() // Reflection on built-in Ko
@GetMapping("/feed")
public void feed(@RequestParam myEnum: MyEnum)
在我们尝试使用大小写不匹配的字符串之前,这是有效的。为此,我发现了一个类似的问题:
val ordinal = param.toString().toIntOrNull()
// Reflection on built-in Kotlin types is not yet fully supported... so ...
return if (null == ordinal)
try {
type.jvmErasure.java.methods.find { it.name == "valueOf" }!!.invoke(null, param.toString())
} catch (e: Exception) {
type.jvmErasure.java.methods.find { it.name == "valueOf" }!!.invoke(null, param.toString().toUpperCase())
}
else
type.jvmErasure.java.enumConstants[ordinal]
抱歉,这是用Kotlin写的,但应该不难理解。它基本上是在原始字符串上尝试valueOf,然后在大写版本上尝试valueOf,如果它是number,则使用枚举的序数值
我正在寻找一个通用的解决方案,而不是单一枚举的处理程序。灵感来源于
我将使用Java为您提供一个示例解决方案
以下代码大写字符串将转换为Enum
,然后调用valueOf
,但您可以将任何逻辑放入转换方法
@SuppressWarnings({"unchecked", "rawtypes"})
public class CaseInsensitiveStringToEnumConverterFactory implements ConverterFactory<String, Enum> {
@Override
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new CaseInsensitiveStringToEnumConverter(getEnumType(targetType));
}
// ConversionUtils are package private. The method is copy-pasted
private static Class<?> getEnumType(Class<?> targetType) {
Class<?> enumType = targetType;
while (enumType != null && !enumType.isEnum()) {
enumType = enumType.getSuperclass();
}
Assert.notNull(enumType, () -> "The target type " + targetType.getName() + " does not refer to an enum");
return enumType;
}
@SuppressWarnings("unchecked")
private class CaseInsensitiveStringToEnumConverter<T extends Enum> implements Converter<String, T> {
private final Class<T> enumClass;
CaseInsensitiveStringToEnumConverter(Class<T> enumClass) {
this.enumClass = enumClass;
}
@Override
public T convert(String source) {
if (source.isEmpty()) {
return null;
}
source = source.toUpperCase().trim();
return (T)Enum.valueOf(enumClass, source);
}
}
}
样本枚举:
public enum Color {
RED,
BLUE,
GREEN
}
样本控制员:
@RestController
public class MyController {
@RequestMapping("/")
public Map<String, Object> testMethod(@RequestParam("color") Color color) {
Map<String, Object> map = new HashMap<>();
map.put("color", color);
return map;
}
}
输出:
{"color":"RED"}
$ curl 'localhost:8080/?color=red'
{"color":"RED"}