簡體   English   中英

如何在不使用@JsonCreator的情況下將請求參數中的integer轉換為枚舉類型字段的枚舉?

[英]How to convert integer in request parameter to enum for a field of enum type without using @JsonCreator?

在我們的項目中,我們定義如下枚舉

public enum GenderEnum implements IEnum{
  MALE(1),
  FEMALE(2);

  private Integer code;

  GenderEnum(int code) {
    this.code = code;
  }

  public static GenderEnum getByCode(int code) {
    for (GenderEnum genderEnum : values()) {
        if (genderEnum.code == code) {
            return genderEnum;
        }
    }
    return null;
  }
}

我們想在用於參數的類中使用這些枚舉,例如

public class Param{
  String id;
  GenderEnum gender;
}

我們有像這樣的控制器

@RestController
class MyController{
  @PostMapping('/alink')
  ResponseBean doSomething(@RequestBody Param param){
      ...
  }
}

對於上述情況,當請求正文為

{"id":"L323", "gender":1}

我們希望1可以轉換為枚舉MALE

一種解決方案是在getByCode(int code)上添加@JsonCreator 。但是在我們現有的項目中,存儲庫層將 enum 轉換為其字符串值( MALEFEMALE )而不是code值,然后再將它們插入數據庫。 因此,如果我們在getByCode(int code)上添加@JsonCreator ,我們會在嘗試從數據庫中檢索枚舉時遇到錯誤。

我們如何使 mvc/controller 將輸入的 integer 值轉換為枚舉而不影響存儲庫層?

我看到一個解決方案如下:

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {

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



static class EnumConverterFactory implements ConverterFactory<Integer, IEnum> {
    @Override
    public <T extends IEnum> Converter<Integer, T> getConverter(Class<T> targetType) {
        if (!targetType.isEnum()) {
            throw new UnsupportedOperationException(targetType + "is not enum");
        }
        return new EnumConverter(targetType);
    }

    private static class EnumConverter<T extends IEnum> implements Converter<Integer, T> {
        private final Class<T> enumType;

        public EnumConverter(Class<T> enumType) {
            this.enumType = enumType;
        }

        @Override
        public T convert(Integer code) {
            for (T t : enumType.getEnumConstants()) {
                if (code.equals(t.getCode())) {
                    return t;
                }
            }
            return null;
        }
    }
}

但這個解決方案不起作用。 調試時,我注意到參數的解析取決於傑克遜的序列化(它根據序數而不是代碼值將 integer 轉換為枚舉)並且根本不涉及轉換器。

那么,有什么解決方法嗎?

您可以在 controller 中聲明用於自定義映射特定類型參數的方法:

@InitBinder
public void initBinder(WebDataBinder dataBinder) {

        dataBinder.registerCustomEditor(GenderEnum.class,
            new PropertyEditorSupport() {
                @Override
                public void setAsText(String value){                    
                    setValue(GenderEnum.getByCode(Integer.parseInt(value));
                }               
            });     
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM