使用枚举有时候会给我们带来了一些困扰:
前端展示数据,需要将枚举转成用户可读的数据显示。
代码中的枚举类型要存储数据库得转成数值类型。
那么本文介绍一种自动转换方案,大大方便前后端使用枚举类型
我们以用户状态为例,用户有两种状态:禁用和启用
第一步创建统一的枚举基类BaseEnum
java
public interface BaseEnum {
int getCode();
String getName();
String getEnumName();
static <T extends BaseEnum> T getInstance(Class<T> clazz, String value) {
T[] constants = clazz.getEnumConstants();
for (T t : constants) {
if(StrUtil.isNumeric(value)){
if (t.getCode() == Integer.parseInt(value)) {
return t;
}
}else {
if (t.getEnumName().equals(value)) {
return t;
}
}
}
return null;
}
}
第二步创建用户状态类StatusEnum
实现BaseEnum
接口
java
public enum StatusEnum implements BaseEnum {
ENABLE(0,"启用"),
DISABLE(1,"禁用");
@EnumValue
private int code;
private String name;
StatusEnum(int code, String name) {
this.code = code;
this.name=name;
}
@Override
public int getCode() {
return code;
}
@Override
public String getName() {
return name;
}
@Override
public String getEnumName() {
return this.name();
}
}
BaseEnum
主要有三个方法
-
getCode()
获取枚举的数值如“0、1”; -
getName()
获取枚举显示值如“禁用、启用” ; -
getEnumName()
获取枚举的枚举值如“ENABLE、DISABLE”.
第三步创建用户类User
用户状态使用StatusEnum
类
java
@Data
@TableName("user")
public class User {
private Long id;
private String userName;
private StatusEnum status;
}
前后端相互转换
当前端查询用户时,我们希望将枚举的三个属性都返回给前端,前端页面显示时取status.name
代码中使用status.enum
或者status.code
json
{
"id": 3581209395268,
"userName": "test2@8531.cn",
"status": {
"name": "禁用",
"enum": "DISABLE",
"code": 1
}
}
为了达到将枚举序列化成一个json对象,我们需要自定义序列化器和反序列化器,以下以SpringBoot自带的Jackson为例:
java
public class BaseEnumSerializer extends StdSerializer<BaseEnum> {
public BaseEnumSerializer() {
this(null);
}
public BaseEnumSerializer(Class<BaseEnum> t) {
super(t);
}
@Override
public void serialize(BaseEnum value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("name",value.getName());
gen.writeStringField("enum",value.getEnumName());
gen.writeNumberField("code",value.getCode());
gen.writeEndObject();;
}
}
public class BaseEnumDeserializer<T extends BaseEnum> extends StdDeserializer<T> {
private Class<T> type;
public BaseEnumDeserializer() {
this(null);
}
public BaseEnumDeserializer(Class<T> vc) {
super(vc);
type = vc;
}
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return BaseEnum.getInstance(type, p.getText());
}
}
java
'public class NumBaseEnumConverterFactory implements ConverterFactory<Number, BaseEnum> {
@Override
public <T extends BaseEnum> Converter<Number, T> getConverter(Class<T> aClass) {
return new NumberToEnumConverter<>(aClass);
}
private final class NumberToEnumConverter<T extends BaseEnum> implements Converter<Number, T> {
private Class<T> enumType;
public NumberToEnumConverter(Class<T> enumType) {
this.enumType = enumType;
}
@Override
public T convert(Number s) {
return BaseEnum.getInstance(enumType,s.toString());
}
}
}
public class StrBaseEnumConverterFactory implements ConverterFactory<String, BaseEnum> {
@Override
public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> aClass) {
return new StringToEnumConverter<>(aClass);
}
private final class StringToEnumConverter<T extends BaseEnum> implements Converter<String, T> {
private Class<T> enumType;
public StringToEnumConverter(Class<T> enumType) {
this.enumType = enumType;
}
@Override
public T convert(String s) {
return BaseEnum.getInstance(enumType,s);
}
}
}
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(BaseEnum.class, new BaseEnumSerializer());
module.addDeserializer(BaseEnum.class, new BaseEnumDeserializer<>());
mapper.registerModule(module);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper;
}
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new StrBaseEnumConverterFactory());
registry.addConverterFactory(new NumBaseEnumConverterFactory());
}
}
查询用户
application/json格式传参
对应JAVA代码:
JAVA
@RestController
public class UserController {
@Resource
private UserMapper userMapper;
@GetMapping("/user/{id}")
public User getById(@PathVariable Long id) {
return userMapper.selectById(id);
}
@PostMapping("/user")
public User upadteById(@RequestBody User user) {
userMapper.updateById(user);
return user;
}
@PutMapping("/user")
public User updateUser(User user) {
userMapper.updateById(user);
return user;
}
@PutMapping("/user/{id}")
public User updateUserStatus(@PathVariable Long id,@RequestParam StatusEnum status) {
User user=userMapper.selectById(id);
user.setStatus(status);
userMapper.updateById(user);
return user;
}
}
这样很方便的解决了枚举在各个环节的自动转换问题,其它枚举只要实现BaseEnum
接口就能实现全自动转换,前后端用起来也方便了不少。
最后说一句(求关注!别白嫖!)
如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!