Spring - Enum in RestControllers?



我知道这个领域已经有很多话题了,但是没有一个能让我满意的答案。我有以下端点和enum:

@RestController
public class MyController {
@PostMapping
public void doStuff(@RequestParam MyEnum myEnum){
...
}
}
public enum MyEnum {
PROPERTY_A("foo"),
PROPERTY_B("bar");
private String name;
MyEnum(String name) {
this.name = name;
}
}

我想注册一个自定义转换器,将foo和bar的字符串值转换为PROPERTY_A, PROPERTY_B的正确enum值。有些东西应该很容易解决,用一个简单的@Override在某个地方劫持标准转换器,无法转换这个,然而我看到的所有答案都要求你在三四个地方注册代码,这不是一个令人满意的答案。

应该很容易解决,用一个简单的@Override在某处劫持标准转换器

如果你说的标准转换器指的是MyEnum.valueOf(String)方法,那么答案是你不能

因为方法valueOf()static没有覆盖Java中static方法的概念。更有趣的是,valueOf(String)甚至不存在于隐式父类java.lang.Enum中,它由编译器以及values()方法在编译过程中添加到每个枚举中。

换句话说,您无法以任何方式控制valueOf(String)方法。

3 - 4位的寄存器码

由于您的方法doStuff()期望MyEnum的实例,而您没有提到任何其他枚举类,我假设您只对将字符串转换为MyEnum的成员感兴趣。您可以通过在MyEnum中添加一个方法来实现这一点(不需要在多个地方引入新代码):

public enum MyEnum {
PROPERTY_A("foo"),
PROPERTY_B("bar");

private String name;

MyEnum(String name) {
this.name = name;
}

public static MyEnum getByName(String name) {
return Arrays.stream(values())
.filter(e -> e.name.equals(name))
.findFirst()
.orElseThrow(); // throw NoSuchElementException if no constant with a matching property has been found
}
}

方法getByName()将抛出NoSuchElementException,如果给定名称的enum-member不存在。

如果您对这样的行为不满意,您可以更改实现。例如,返回一个可选对象(这比返回null更可取):

public static Optional<MyEnum> getByName(String name) {
return Arrays.stream(values())
.filter(e -> e.name.equals(name))
.findFirst();
}

或者您可以使用orElse()代替orElseThrow()来返回一个特定的枚举常量,这将表示缺少数据,即实现空对象模式

相关内容

  • 没有找到相关文章