通过 Jackson/Spring REST 资源反序列化枚举字段

Deserializing enum field via Jackson/Spring REST resource

请注意:我在此处使用 Spring 引导,而不是 Spring MVC。

Java 8 和 Spring Boot/Jackson 这里。我有以下枚举:

public enum OrderType {

    PARTIAL("partialOrder"),
    FULL("fullOrder");

    private String label;

    OrderType(String label) { this.label = label; }

}

我想公开一个 POST 客户端可以将 OrderType#label 作为请求参数的端点,并且 Spring 将知道将提供的标签转换为 OrderType 像这样:

@PostMapping("/v1/myapp/orders")
public ResponseEntity<?> acceptOrder(@RequestParam(value = "orderType") OrderType orderType) {
    // ...
}

因此客户端可以调用 POST /v1/myapp/orders?orderType=fullOrder 并且在服务器上,控制器将收到一个 OrderType 实例。

我怎样才能做到这一点?

这太简单了,穴居人也能做到。

枚举:

public class MyEnum {
    FIZZ("sumpin"),
    BUZZ("sumpinElse");

    @JsonValue
    private String label;

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

    public String getLabel() { return this.label; }

    public static Optional<MyEnum> toMyEnum(String label) {
        if (label == null) {
            return Optional.empty();
        }

        for (MyEnum mine : MyEnum.values()) {
            if (label.equals(mine.getLabel()) {
                return Optional.of(mine);
            }
        }

        throw new IllegalArgumentException("no supported");

    }

}

Spring转换器:

public class MyEnumConverter implements Converter<String,MyEnum> {

    @Override
    public MyEnum convert(String label) {

        Optional<MyEnum> maybeMine = MyEnum.toMyEnum(label);
        if (maybeMine.isPresent()) {
            return maybeMine.get():
        }

        // else, you figure out what you want your app to do,
        // thats not my job!

    }

}

注册它:

@Configuration
public class YourAppConfig {

    @Autowired
    public void configureConverter(FormatterRegistry registry) {
        registry.addConverter(new MyEnumConverter());
    }

}

从内部支持它 controller/resource:

@Post("/v1/foobar/doSomething")
public ResponseEntity<?> doSomething(@RequestParam(value = "mine") MyEnum mine) {
    // ... whatever
}

在 API 调用中使用该死的东西:

POST http://yourlousyapp.example.com/v1/foobar/doSomething?mine=sumpin