我应该怎么做才能在 spring 启动 http 请求中接收枚举数据

what should I do to receive enum data in spring boot http request

现在我有一个简单的枚举,叫做 AppName:

package misc.enumn.app;

import lombok.Getter;
import misc.enumn.BaseEnum;

/**
 * @author dolphin
 */
@Getter
public enum AppName implements BaseEnum {
    CRUISE( 1, "cruise"),
    BACK(2, "back"),
    ;
    private Integer key;
    private String value;

    AppName(Integer key, String value) {
        this.key = key;
        this.value = value;
    }

    public void setKey(Integer key) {
        this.key = key;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public static AppName getAppMarkByValue(String value) {
        AppName datetimeType = null;
        for (AppName type : AppName.values()) {
            if (type.name().equals(value)) {
                datetimeType = type;
            }
        }
        return datetimeType;
    }

    public static AppName getAppMarkByKey(Short key) {
        AppName datetimeType = null;
        for (AppName type : AppName.values()) {
            if (type.key.equals(key)) {
                datetimeType = type;
            }
        }
        return datetimeType;
    }
}

然后我这样定义一个请求对象:

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserLoginRequest implements Serializable {

    @ApiModelProperty(value = "app")
    private AppName app;

}

当我向服务器端传递appId 1时,服务器将AppName解析为BACK,我不明白为什么它解析为BACK而不是'CRUISE'?我已经定义了枚举解析器:

public class IntegerCodeToEnumConverterFactory implements ConverterFactory<Integer, BaseEnum> {

    private static final Map<Class, Converter> CONVERTERS = Maps.newHashMap();

    @Override
    public <T extends BaseEnum> Converter<Integer, T> getConverter(Class<T> targetType) {
        Converter<Integer, T> converter = CONVERTERS.get(targetType);
        if (converter == null) {
            converter = new IntegerToEnumConverter<>(targetType);
            CONVERTERS.put(targetType, converter);
        }
        return converter;
    }

}

并添加到拦截器配置:

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

但似乎仍然无法解析枚举,我应该怎么做才能正确解析应用程序?这是错误的解析(我希望 1 解析为 CRUISE,2 解析为 BACK):

顺便说一句,当我将应用程序从枚举替换为整数时,它可以正确解析它(接收值 1)。但我认为使用枚举可能更易读。

public class IntegerToEnumConverter <T extends BaseEnum> implements Converter<Integer, T> {
    private Map<Integer, T> enumMap = Maps.newHashMap();

    public IntegerToEnumConverter(Class<T> enumType) {
        T[] enums = enumType.getEnumConstants();
        for (T e : enums) {
            enumMap.put(e.getKey(), e);
        }
    }

    @Override
    public T convert(Integer source) {
        T t = enumMap.get(source);
        if (ObjectUtils.isNull(t)) {
            throw new IllegalArgumentException("");
        }
        return t;
    }
}

如果你想在 http post 方法中解析枚举,我所做的只支持 http get 方法。像这样定义代码:

 @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static AppName resolve(Integer key) {
        return mappings.get(key);
    }

这是我的完整代码:

@Getter
public enum AppName implements BaseEnum {
    CRUISE(1, "cruise"),
    BACK(2, "back"),
    ;

    @JsonValue
    private Integer key;
    private String value;

    AppName(Integer key, String value) {
        this.key = key;
        this.value = value;
    }

    private static final Map<Integer, AppName> mappings;

    static {
        Map<Integer, AppName> temp = new HashMap<>();
        for (AppName courseType : values()) {
            temp.put(courseType.key, courseType);
        }
        mappings = Collections.unmodifiableMap(temp);
    }

    @EnumConvertMethod
    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static AppName resolve(Integer key) {
        return mappings.get(key);
    }

    public void setKey(Integer key) {
        this.key = key;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public static AppName getAppMarkByValue(String value) {
        AppName datetimeType = null;
        for (AppName type : AppName.values()) {
            if (type.name().equals(value)) {
                datetimeType = type;
            }
        }
        return datetimeType;
    }

    public static AppName getAppMarkByKey(Short key) {
        AppName datetimeType = null;
        for (AppName type : AppName.values()) {
            if (type.key.equals(key)) {
                datetimeType = type;
            }
        }
        return datetimeType;
    }
}