如何优雅的使用枚举类型,可以这样做!

使用枚举有时候会给我们带来了一些困扰:

前端展示数据,需要将枚举转成用户可读的数据显示。

代码中的枚举类型要存储数据库得转成数值类型。

那么本文介绍一种自动转换方案,大大方便前后端使用枚举类型

我们以用户状态为例,用户有两种状态:禁用和启用

图片

图片

第一步创建统一的枚举基类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主要有三个方法

  1. getCode()获取枚举的数值如“0、1”;

  2. getName()获取枚举显示值如“禁用、启用” ;

  3. 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实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值