• SpringBoot传参转换枚举


    有时候,我们传参的时候,希望使用枚举类来当作参数

    public enum VipEnum {
    HUANG(1, "黄钻"),
    HONG(2, "红钻");
    private Integer id;
    private String value;

    VipEnum(Integer id, String value) {
    this.id = id;
    this.value = value;
    }

    public Integer getId() {
    return id;
    }

    public String getValue() {
    return value;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    我们期望的是这样,参数中传一个1 后台就自动转换为枚举类的VipEnum.HUANG

    @PostMapping("/vip")
    public VipEnum convert(VipEnum vipEnum) {
    return vipEnum;
    }

    1
    2
    3
    4
    5
    实现Converter接口
    这时候该怎么办呢?我们开始分析,是不是可以用到spring的类型转换器呢? spring为我们提供了一个类型自动转换接口Converter<S, T>,可以实现从一个Object转为另一个Object的功能。除了Converter接口之外

    public interface Converter<S, T> {
    T convert(S source);
    }
    1
    2
    3
    然后呢我们就稍微实现一下

    @Component
    @Slf4j
    public class PersonConverter implements Converter<String, VipEnum> {

    @Override
    public VipEnum convert(String value) {
    log.info("参数是: {}", value);
    return (VipEnum) PersonConverter.getEnum(VipEnum.class, value);
    }


    public static <T extends VipEnum> Object getEnum(Class<T> targerType, String source) {
    for (T enumObj : targerType.getEnumConstants()) {
    if (source.equals(String.valueOf(enumObj.getId()))) {
    return enumObj;
    }
    }
    return null;
    }

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    这样呢就实现了转换,需要注意啊 在Spring MVC和Spring Boot中,由于从客户端接收到的请求都被视为String类型,所以只能用String转枚举的converter。

    ConverterFactory接口
    ConverterFactory的出现可以让我们统一管理一些相关联的Converter。顾名思义,ConverterFactory就是产生Converter的一个工厂,确实ConverterFactory就是用来产生Converter的。我们先来看一下ConverterFactory接口的定义

    public interface ConverterFactory<S, R> {
    <T extends R> Converter<S, T> getConverter(Class<T> targetType);
    }
    1
    2
    3
    可以看出 总共有 三个泛型S、R、T,其中

    S表示原类型
    R表示目标类型
    T是类型R的一个子类
    ConverterFactory相比converter的好处在于ConverterFactory可以将原类型转换成一组实现了相同接口类型的对象,而Converter则只能转换成一种类型,总不能一个枚举去实现一个Converter啊,这样肯定不行的。有了ConverterFactory之后,事情就变得简单了不少!

    首先弄个基类接口

    public interface IEnum<T> {
    T getId();
    }
    1
    2
    3
    然后让枚举类实现它

    public enum VipEnum implements IEnum<Integer> {
    HUANG(1, "黄钻"),
    HONG(2, "红钻");
    private Integer id;
    private String value;

    VipEnum(Integer id, String value) {
    this.id = id;
    this.value = value;
    }

    @Override
    public Integer getId() {
    return id;
    }

    public String getValue() {
    return value;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    然后创建一个枚举工厂转换类

    @Component
    public class EnumConvertFactory implements ConverterFactory<String, IEnum> {
    @Override
    public <T extends IEnum> Converter<String, T> getConverter(Class<T> targetType) {
    return new StringToIEum<>(targetType);
    }

    @SuppressWarnings("all")
    private static class StringToIEum<T extends IEnum> implements Converter<String, T> {
    private Class<T> targerType;
    public StringToIEum(Class<T> targerType) {
    this.targerType = targerType;
    }

    @Override
    public T convert(String source) {
    if (StringUtils.isEmpty(source)) {
    return null;
    }
    return (T) EnumConvertFactory.getIEnum(this.targerType, source);
    }
    }

    public static <T extends IEnum> Object getIEnum(Class<T> targerType, String source) {
    for (T enumObj : targerType.getEnumConstants()) {
    if (source.equals(String.valueOf(enumObj.getId()))) {
    return enumObj;
    }
    }
    return null;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    这样还不行,紧接着,需要把转换工厂注入spring容器,这里呢我使用的是springbooot2.x

    @Configuration
    public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private EnumConvertFactory enumConvertFactory;

    @Override
    public void addFormatters(FormatterRegistry registry) {
    registry.addConverterFactory(enumConvertFactory);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    然后来就可以进行转换了,需要转换的枚举实现基类接口就可以啦,是不是棒棒的!!

  • 相关阅读:
    Feign调用文件上传服务接口样例
    Feign调用文件下载服务接口样例
    使用Spring Security的Basic Auth认证后Postman的POST请求不成功的可能原因
    Spring Boot应用的Controller返回的集合类数据是XML格式的可能原因
    Eureka Server增加Spring Security后的服务端和客户端配置
    Spring Data支持的关键字
    JPA(Hibernate)代理类的hibernateLazyInitializer属性系列化异常
    Spring Boot中fastjson的@JSONField(format = "yyyy-MM-dd HH:mm:ss")失效可能原因
    使用Java代码配置MyBatis Generator
    CentOS8.1中搭建Nexus3服务器
  • 原文地址:https://www.cnblogs.com/hyhy904/p/10962037.html
Copyright © 2020-2023  润新知