【问题标题】:Deserializing enum field via Jackson/Spring REST resource通过 Jackson/Spring REST 资源反序列化枚举字段
【发布时间】:2021-09-07 04:22:20
【问题描述】:

请注意:我在这里使用的是 Spring Boot,而不是 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 实例。

我怎样才能做到这一点?

【问题讨论】:

  • 我认为这会减少到this question,答案是“写一个Converter&lt;String, OrderType&gt;”。
  • 是的,谢谢,确实是这样,但问题是我需要使用 FormatterRegistry 注册转换器,我似乎无法在 Spring Boot 中访问. FormatterRegistry 可从实现 WebMvcConfigurer 的 Web 配置获得,这是 Spring MVC 应用程序的标准配置。但是,作为 Spring Boot 应用程序,这实现了WebSecurityConfigurerAdapter
  • 您似乎误解了 Spring Boot 是什么。它是一组用于 Spring 应用程序的配置实用程序。您使用 Spring MVC 模块来提供 Web 服务(并且可能使用 Spring Data 进行数据访问,并且添加更多是常见的)。
  • 哦,太好了,谢谢,您是否有机会提供一些示例代码,向我展示如何访问FomatterRegistry(以便我可以使用它注册我的自定义转换器)?

标签: java spring spring-mvc enums deserialization


【解决方案1】:

这太容易了,一个穴居人甚至可以做到。

枚举:

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");

    }

}

弹簧转换器:

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());
    }

}

在控制器/资源中从内部支持它:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 2021-12-27
    • 2015-10-19
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    相关资源
    最近更新 更多