下面是枚举接口和一个枚举示例:
public interface Enumerable<E extends Enumerable> {
/**
* 获取在i18n文件中对应的 key
* @return key
*/
@Nonnull
String getKey();
/**
* 获取最终保存到数据库的值
* @return 值
*/
@Nonnull
int getValue();
/**
* 获取 key 对应的文本信息
* @return 文本信息
*/
@Nonnull
default String getText() {
return I18nMessageUtil.getMessage(this.getKey(), null);
}
}
public enum GenderEnum implements Enumerable {
/** 男 */
MALE(1, "male"),
/** 女 */
FEMALE(2, "female");
private int value;
private String key;
GenderEnum(int value, String key) {
this.value = value;
this.key = key;
}
@Override
public String getKey() {
return this.key;
}
@Override
public int getValue() {
return this.value;
}
}
我们要做的就是,每个我们编写的枚举类,都需要按这样的方式进行编写,按照规范定义的枚举类方便下面统一编写。
2、我们分析下controller层面的数据进和出,从而处理好枚举类和int值的转换,在Spring MVC中,框架帮我们做了数据类型的转换,所以我们以 Spring MVC作为切入点。前台发送到服务端的请求,一般有参数在url中和body中两种方式为主,分别以get请求和post请求配合@RequestBody为代表。
【入参】get方法为代表,请求的MediaType为"application/x-www-form-urlencoded",此时将 int 转换成枚举,我们注册一个新的Converter,如果spring MVC判断到一个值要转换成我们定义的枚举类对象时,调用我们设定的这个转换器
@Configuration
public class MvcConfiguration implements WebMvcConfigurer, WebBindingInitializer {
/**
* [get]请求中,将int值转换成枚举类
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new EnumConverterFactory());
}
}
public class EnumConverterFactory implements ConverterFactory<String, Enumerable> {
private final Map<Class, Converter> converterCache = new WeakHashMap<>();
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public <T extends Enumerable> Converter<String, T> getConverter(@Nonnull Class<T> targetType) {
return converterCache.computeIfAbsent(targetType,
k -> converterCache.put(k, new EnumConverter(k))
);
}
protected class EnumConverter<T extends Enumerable> implements Converter<Integer, T> {
private final Class<T> enumType;
public EnumConverter(@Nonnull Class<T> enumType) {
this.enumType = enumType;
}
@Override
public T convert(@Nonnull Integer value) {
return EnumUtil.of(this.enumType, value);
}
}
}
【入参】post为代表,将 int 转换成枚举。这块我们和前台达成一个约定( Ajax中applicationType),所有在body中的数据必须为json格式。同样后台@RequestBody对应的参数的请求的MediaType为"application/json",spring MVC中对于Json格式的数据,默认使用 Jackson2HttpMessageConverter。在Jackson转换成实体时候,有@JsonCreator和@JsonValue两个注解可以用,但是感觉还是有点麻烦。为了统一处理,我们需要修改Jackson对枚举类的序列化和反序列的支持。配置如下:










