在我们的项目中,我们定义如下枚举
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
一种解决方案是在@JsonCreator
上添加getByCode(int code)
。但是在我们现有的项目中,存储库层将枚举转换为它的String值(MALE
或FEMALE
),但不是将它们插入数据库之前先输入code
值。因此,如果在@JsonCreator
上添加getByCode(int code)
,则在尝试从数据库检索枚举时会遇到错误。
如何使mvc / controller将输入的整数值转换为枚举而不影响存储库层?
我看到以下解决方案:
@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;
}
}
}
,但是此解决方案不起作用。调试时,我注意到参数的解析取决于Jackson的序列化(序列化是根据序数而不是代码值将整数转换为枚举),并且转换器根本不涉及。
那么,有什么解决方法吗?
答案 0 :(得分:-1)
您可以在控制器中声明用于特定类型参数的自定义映射的方法:
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(GenderEnum.class,
new PropertyEditorSupport() {
@Override
public void setAsText(String value){
setValue(GenderEnum.getByCode(Integer.parseInt(value));
}
});
}