【Spring Boot 枚举类型的自动转换】

1、Spring Boot 枚举类型的自动转换
需求:一般我们在数据库都会定义数值型的枚举常量,不管是序列化还是反序列化都是需要我们手动去转换成枚举类型的,既然这样我们能不能让它们自动转换呢?接下来我们就来尝试一下:
首先解决如何接收枚举类型。
枚举父类
/**

  • @author rookie
    */
    public interface IEnum {

    /**

    • 获取值
    • @return 值
      */
      T getValue();
      }

1.1、请求头接收参数
添加Convert
@Component
public class EnumConvertFactory implements ConverterFactory<String, IEnum<?>> {

@Override
public <T extends IEnum<?>> Converter<String, T> getConverter(Class<T> targetType) {
    return new StringToEnum<>(targetType);
}


public static class StringToEnum<T extends IEnum<?>> implements Converter<String, T> {

    private final Class<T> targetType;

    public StringToEnum(Class<T> targetType) {
        this.targetType = targetType;
    }

    @Override
    public T convert(String source) {
        if (!StringUtils.hasText(source)) {
            return null;
        }
        return (T) EnumConvertFactory.getEnum(this.targetType, source);
    }
}

public static <T extends IEnum<?>> T getEnum(Class<T> targetType, String source) {
    for (T constant : targetType.getEnumConstants()) {
        if (source.equals(String.valueOf(constant.getValue()))) {
            return constant;
        }
    }
    return null;
}

}

注册Convert
@Configuration
public class WebConfig implements WebMvcConfigurer {

@Autowired
private EnumConvertFactory enumConvertFactory;

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

}

我们只要实现 IEnum ,然后在我们的接收实体类中定义相应的枚举类型就能自动转换成枚举类型了,比如这样:
@Getter
@AllArgsConstructor
public enum TestEnum implements IEnum{

/**
 * 测试
 */
TEST_ENUM("1","2");

private final String value;

private final String msg;

}

1.2、请求体接收
Jackson接收枚举
如果我们接收的是 JSON 字符串类型,那么 Jackson 默认是根据下标进行转换的,和我们根据匹配值获取相应枚举不符,所以进行以下更改:
添加枚举反序列化处理器
@Data
@EqualsAndHashCode(callSuper = true)
public class EnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {

private Class<?> target;

@SuppressWarnings("all")
@Override
public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
    if (!StringUtils.hasText(jsonParser.getText())) {
        return null;
    }
    if (IEnum.class.isAssignableFrom(target)) {
        return (Enum<?>) EnumConvertFactory.getEnum((Class) target, jsonParser.getText());
    }
    return null;
}

/**
 * @param ctx      ctx
 * @param property property
 * @return 1
 * @throws JsonMappingException
 */
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) throws JsonMappingException {
    Class<?> rawCls = ctx.getContextualType().getRawClass();
    EnumDeserializer enumDeserializer = new EnumDeserializer();
    enumDeserializer.setTarget(rawCls);
    return enumDeserializer;
}

}

注册处理器
@Component
public class JacksonConfig implements SmartInitializingSingleton {

@Autowired
private ObjectMapper objectMapper;

@Override
public void afterSingletonsInstantiated() {
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addDeserializer(Enum.class, new EnumDeserializer());
    objectMapper.registerModule(simpleModule);
}	

}

使用方法和上面一致。
1.3、添加自定义枚举序列化
接下来我们就要解决如何将数据库中的数值常量枚举转换成
jackson 序列化默认是按照名称序列化的,和我们想返回枚举中的某个值不符,下面我们进行一下小的改动:
添加序列化处理器
public class IEnumSerializer extends JsonSerializer {
@Override
public void serialize(IEnum iEnum, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(iEnum.getName());
}
}

注册序列化处理器
@Component
public class BeanLoadProcess implements SmartInitializingSingleton {

@Autowired
private ObjectMapper objectMapper;

@Override
public void afterSingletonsInstantiated() {
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(IEnum.class,new IEnumSerializer());
    objectMapper.registerModule(simpleModule);
}

}

因为我们先一步是让数据库中的常量能转换成枚举类型,这里我们定义一下 Mybatis plus(我用的是plus) 的枚举处理器
mybatis-plus:
configuration:
default-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler

好了这样就行了。

最后
如果您觉得此文章对您有一丁点帮助,点个赞。或者可以添加我15129888268,拉你进开发交流群相互学习,我们会有专业的技术答疑解惑,免费赠送商城源码搭建使用。CRMEB专注移动互联网电商系统多年,有专业的技术团队和售后团队。

PHP学习手册:https://doc.crmeb.com
技术交流论坛:https://q.crmeb.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开源商城源码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值