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

目录
  • 1、请求头接收参数
  • 2、请求体接收
  • 3、添加自定义枚举序列化

需求:一般我们在数据库都会定义数值型的枚举常量,不管是序列化还是反序列化都是需要我们手动去转换成枚举类型的,既然这样我们能不能让它们自动转换呢?接下来我们就来尝试一下:

首先解决如何接收枚举类型。

枚举父类

/**
 * @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 枚举类型的自动转换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring boot JPA实现分页和枚举转换代码示例

    1.实现分页 方法一:使用Pageable 使用Pageable作为入参传入Repository,返回值用Page<T>接收 UserRepository package com.kinglead.demo.dao; ​ import com.kinglead.demo.entity.User; import org.springframework.data.jpa.repository.JpaRepository; ​ public interface UserRepository exte

  • SpringBoot实战:Spring如何找到对应转换器优雅使用枚举参数

    目录 找入口 请求入口是DispatcherServlet 查找转换器 Spring 如何查找转换器 类型转换 跟随源码找到自定义转换器工厂类和转换器类的实现逻辑 无论是GET请求,还是传参式的POST请求(即Form模式) 找入口 请求入口是DispatcherServlet 所有的请求最终都会落到doDispatch方法中的 ha.handle(processedRequest, response, mappedHandler.getHandler())逻辑. 我们从这里出发,一层一层向里扒

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

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

  • springboot枚举类型传递的步骤

    目录 测试 Converter 灵活化 在本周写项目时,需要将枚举类型作为参数进行传递. 测试 首先先建立一个枚举类: public enum ScoreType { TOTAL_SCORE("总评成绩"), MIDDLE_SCORE("期中成绩"), FINAL_SCORE("期末成绩"); String des; // 描述 ScoreType(String des) { this.des = des; } public String get

  • 详解Spring MVC自动为对象注入枚举类型

    如果一个对象里面有枚举类型的话,则spring MVC是不能够直接进行注入的,因为它只实现了一些基本的数据类型的自动转换注入,但是其也提供了可扩展的接口,可以根据自己的需要来进行扩展.下面是一个示例: 首先:这是一个枚举类: /** * 新闻类别 * @author: ShangJianguo * 2014-6-11 上午10:51:07 */ public enum ENews { company("0"), // 企业新闻 industry("1");// 行业

  • Struts2单选按钮详解及枚举类型的转换代码示例

    本文研究的主要是Struts2框架单选按钮详解及枚举类型的转换的相关示例,具体如下. 使用struts2标签,毫无疑问要先引入标签库: <%@ taglib prefix="s" uri="/struts-tags"%> 假设radio单选框中List的值为一个Map集合: <s:radio list="#{'MAN':'男','WOMEN':'女'}" name="gender" listKey="

  • SpringBoot配置mybatis驼峰命名规则自动转换的实现

    一.简述 mybatis驼峰式命名规则自动转换: 使用前提:数据库表设计按照规范"字段名中各单词使用下划线"_"划分": 使用好处:省去mapper.xml文件中繁琐编写表字段列表与表实体类属性的映射关系,即resultMap. 示例: <resultMap id ="UserInfoMap" type="com.example.mybaitsxml.dao.entity.User"> <result col

  • java中的类型自动转换机制解析

    目录 类型自动转换机制解析 概述 数据类型只会自动提升,不能自动降低 Java中整数默认的数据类型是int类型 自动类型转换&强制类型转换 什么时候会发生类型转换 类型转换分类 自动类型转换(隐式类型转换) 强制类型转换(显式类型转换) 类型自动转换机制解析 概述 自动类型转换也叫隐式类型转换 表达式的数据类型自动提升 所有的byte型.short型和char的值将被提升到int型. 如果一个操作数是long型,计算结果就是long型: 如果一个操作数是float型,计算结果就是float型:

  • SpringBoot Entity中枚举类型详细使用介绍

    目录 简介方案对比 枚举用法示例 建表 Entity Enum Controller Service Mapper 测试 1.正常操作 2.前端传空字符串 3.前端传null 简介方案对比 本处列举表示类型或状态的常用方法的对比. 法1:使用数字表示(不推荐) //1:支付宝支付:2:微信支付:3:银行卡支付 private Integer payType; 这种方法的缺点:可读性极差,排查问题也麻烦.比如:前端页面上看到了2这个类型,还要看接口文档或者问后端这是什么意思,浪费时间! 法2:使用

  • C#编程中枚举类型的使用教程

    枚举类型(也称为枚举)为定义一组可以赋给变量的命名整数常量提供了一种有效的方法.例如,假设您必须定义一个变量,该变量的值表示一周中的一天.该变量只能存储七个有意义的值.若要定义这些值,可以使用枚举类型.枚举类型是使用 enum关键字声明的. enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; enum Months : byte { Jan, Feb, Mar, Apr, May, Jun,

  • Spring MVC处理参数中的枚举类型通用实现方法

    前言 在开发的过程中,会涉及到大量的枚举类型数据,我们都知道,Springmvc本身能自动转换很多的数据类型,也支持你自定义转换类型,非常灵活. 本文主要介绍的是关于Spring MVC处理参数的枚举类型通用实现的相关内容,下面话不多说了,来一起看看详细的介绍吧 业务场景: 前端提交了枚举的一个属性value,想由spring来完成参数类型自动转换成对应的枚举. 比方有一个枚举 @AllArgsConstructor(access = AccessLevel.PRIVATE) @Getter @

  • 秒懂Java枚举类型(enum)

    理解枚举类型 枚举类型是Java 5中新增特性的一部分,它是一种特殊的数据类型,之所以特殊是因为它既是一种类(class)类型却又比类类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁性.安全性以及便捷性.下面先来看看什么是枚举?如何定义枚举? 枚举的定义 上述的常量定义常量的方式称为int枚举模式,这样的定义方式并没有什么错,但它存在许多不足,如在类型安全和使用方便性上并没有多少好处,如果存在定义int值相同的变量,混淆的几率还是很大的,编译器也不会提出任何警告,因此这种方式在枚举

随机推荐