首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring枚举识别

Spring枚举识别
EN

Stack Overflow用户
提问于 2018-07-31 15:27:36
回答 1查看 979关注 0票数 0

在控制器中,我们希望使用枚举作为方法参数:

代码语言:javascript
复制
@GetMapping("/feed")
public void feed(@RequestParam myEnum: MyEnum)

这是可行的,直到我们尝试使用字符串不匹配的情况下。为此,我发现了一个类似的问题:

但是,这需要为每个枚举设置处理程序。我宁愿为所有枚举实现我的自定义处理程序。类似于:

代码语言:javascript
复制
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,然后在大写版本上尝试,如果它是数字,它使用枚举的序号值。

我正在寻找一个通用的解决方案,而不是单个枚举的处理程序。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-31 17:01:05

StringToEnumConverterFactory的启发。

我将使用Java为您提供一个示例解决方案。

下面的代码大写字符串将被转换为Enum,然后调用valueOf,但是您可以将任何逻辑放入转换方法。

代码语言:javascript
复制
@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);
    }
  }
}

MvcConfig:

代码语言:javascript
复制
@Configuration
public class MvcConfig implements WebMvcConfigurer {

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

样品枚举:

代码语言:javascript
复制
public enum Color {
  RED,
  BLUE,
  GREEN
}

SampleContoller:

代码语言:javascript
复制
@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;
  }
}

测试:

代码语言:javascript
复制
$ curl 'localhost:8080/?color=red'

输出:

代码语言:javascript
复制
{"color":"RED"}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51616991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档