首页 > 解决方案 > Java REST Enum 序列化和 Spring

问题描述

在使用Spring MVC的 REST api 中,如果我想将可以作为 http GET 请求参数传递的字符串值限制为以下之一

值A 值B

我想我应该在 java 中使用 Enum 类型。

public enum MyEnum {

    @JsonProperty("valueA")
    VALUE_A("valueA"),
    @JsonProperty("valueB")
    VALUE_B("valueB");

    private final String label;

    private MyEnum(String label) {
        this.label = label;
    }
    
    @Override 
    public String toString() { 
        return this.label; 
    }
    
    @JsonValue
    public String getLabel() {
        return label;
    }
}

然而,这只处理枚举的序列化。当我在弹簧控制器中收到valueArequestParam 时,有一个ConversionFailedException因为

我已阅读以下文章https://www.baeldung.com/spring-enum-request-param但我的问题是,有没有比编写自定义转换器更简单的解决方案。

我不想为我想在我的 REST api 中交换的每个枚举编写和注册一个转换器。

我也试过这个,但是 spring mvc 似乎没有调用 forValue 来反序列化参数。

公共枚举 MyEnum {

VALUE_A("valueA"),
VALUE_B("valueB");

private final String label;

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

@Override 
public String toString() { 
    return this.label; 
}

@JsonValue
public String getLabel() {
    return label;
}

@JsonCreator
public MyEnum forValue(String label) {
            
        for (MyEnum enum: MyEnum .values()) {
            if (enum.getLabel().equals(label)) {
                return enum;
            }
        }
        throw new IllegalArgumentException("Can't find MyEnum Enum to match :" + label);
    }

}

标签: javaspringrestenums

解决方案


如果您不想编写转换器,您当然可以回退到 Spring 的StringToEnumConverterFactory,它要求您按字面意思发送 Enum 文字 - 所以在您的情况下VALUE_AVALUE_B. 如果您决定通过除字面量之外的任何其他值来识别枚举,则只需要一个更复杂的转换器,但请注意,拥有自己的转换器的方法有它的警告,正如我们在您的示例中看到的那样,因为与 Enum 相比文字(由编译器检查是否唯一)例如,您的值不必是唯一的,就像在您的示例中,两个文字都具有值“valueA”,因此映射不会是不同的。


推荐阅读