SpringBoot|SpringBoot 枚举类型的自动转换的实现

目录

  • 1、请求头接收参数
  • 2、请求体接收
  • 3、添加自定义枚举序列化
需求:一般我们在数据库都会定义数值型的枚举常量,不管是序列化还是反序列化都是需要我们手动去转换成枚举类型的,既然这样我们能不能让它们自动转换呢?接下来我们就来尝试一下:
首先解决如何接收枚举类型。
枚举父类
/** * @author rookie */public interface IEnum {/*** 获取值* @return 值*/T getValue(); }


1、请求头接收参数 添加Convert
@Componentpublic class EnumConvertFactory implements ConverterFactory> {@Overridepublic > Converter getConverter(Class targetType) {return new StringToEnum<>(targetType); }public static class StringToEnum> implements Converter {private final Class targetType; public StringToEnum(Class targetType) {this.targetType = targetType; }@Overridepublic T convert(String source) {if (!StringUtils.hasText(source)) {return null; }return (T) EnumConvertFactory.getEnum(this.targetType, source); }}public static > T getEnum(Class targetType, String source) {for (T constant : targetType.getEnumConstants()) {if (source.equals(String.valueOf(constant.getValue()))) {return constant; }}return null; }}

注册Convert
@Configurationpublic class WebConfig implements WebMvcConfigurer {@Autowiredprivate EnumConvertFactory enumConvertFactory; @Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverterFactory(enumConvertFactory); }}

我们只要实现 IEnum ,然后在我们的接收实体类中定义相应的枚举类型就能自动转换成枚举类型了,比如这样:
@Getter@AllArgsConstructorpublic enum TestEnum implements IEnum{/*** 测试*/TEST_ENUM("1","2"); private final String value; private final String msg; }


2、请求体接收 Jackson接收枚举
如果我们接收的是 JSON 字符串类型,那么 Jackson 默认是根据下标进行转换的,和我们根据匹配值获取相应枚举不符,所以进行以下更改:
添加枚举反序列化处理器
@Data@EqualsAndHashCode(callSuper = true)public class EnumDeserializer extends JsonDeserializer> implements ContextualDeserializer {private Class target; @SuppressWarnings("all")@Overridepublic 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 ctxctx* @param property property* @return 1* @throws JsonMappingException*/@Overridepublic JsonDeserializer createContextual(DeserializationContext ctx, BeanProperty property) throws JsonMappingException {Class rawCls = ctx.getContextualType().getRawClass(); EnumDeserializer enumDeserializer = new EnumDeserializer(); enumDeserializer.setTarget(rawCls); return enumDeserializer; }}

注册处理器
@Componentpublic class JacksonConfig implements SmartInitializingSingleton {@Autowiredprivate ObjectMapper objectMapper; @Overridepublic void afterSingletonsInstantiated() {SimpleModule simpleModule = new SimpleModule(); simpleModule.addDeserializer(Enum.class, new EnumDeserializer()); objectMapper.registerModule(simpleModule); } }

使用方法和上面一致。

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

注册序列化处理器
@Componentpublic class BeanLoadProcess implements SmartInitializingSingleton {@Autowiredprivate ObjectMapper objectMapper; @Overridepublic 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

好了这样就行了。
【SpringBoot|SpringBoot 枚举类型的自动转换的实现】到此这篇关于Spring Boot 枚举类型的自动转换的文章就介绍到这了,更多相关Spring Boot 枚举类型的自动转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读