SpringBoot 枚举类型的自动转换的实现
需求:一般我们在数据库都会定义数值型的枚举常量,不管是序列化还是反序列化都是需要我们手动去转换成枚举类型的,既然这样我们能不能让它们自动转换呢?接下来我们就来尝试一下:
首先解决如何接收枚举类型。
枚举父类
/** * @author rookie */ public interface IEnum<T extends Serializable> { /** * 获取值 * @return 值 */ T getValue(); }
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<String>{ /** * 测试 */ 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<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); } }
使用方法和上面一致。
3、添加自定义枚举序列化
接下来我们就要解决如何将数据库中的数值常量枚举转换成
jackson 序列化默认是按照名称序列化的,和我们想返回枚举中的某个值不符,下面我们进行一下小的改动:
添加序列化处理器
public class IEnumSerializer extends JsonSerializer<IEnum> { @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
好了这样就行了。
到此这篇关于Spring Boot 枚举类型的自动转换的文章就介绍到这了,更多相关Spring Boot 枚举类型的自动转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringBoot结合Mybatis实现创建数据库表的方法
本文主要介绍了SpringBoot结合Mybatis实现创建数据库表的方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2022-01-01SpringBoot详解整合MyBatis过程中可能遇到的问题
因为Spring Boot框架开发的便利性,所以实现Spring Boot与数据访问层框架(例如MyBatis)的整合非常简单,主要是引入对应的依赖启动器,并进行数据库相关参数设置即可2022-07-07ArrayList和JSONArray边遍历边删除到底该如何做
这篇文章主要介绍了ArrayList和JSONArray边遍历边删除到底该如何做,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-12-12SpringBoot2中使用@RequestHeader获取请求头的方法
springMVC/SpringBoot中提供了@RequestHeader注解用来获取请求头。本文就详细的来介绍一下如何使用,感兴趣的可以了解下2021-10-10Java 比较接口comparable与comparator区别解析
这篇文章主要介绍了Java 比较接口comparable与comparator区别解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2019-10-10SpringBoot系列教程之dubbo和Zookeeper集成方法
这篇文章主要介绍了SpringBoot系列教程之dubbo和Zookeeper集成方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-09-09
最新评论