zoukankan      html  css  js  c++  java
  • 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
    然后来就可以进行转换了,需要转换的枚举实现基类接口就可以啦,是不是棒棒的!!

  • 相关阅读:
    ExecuteScalar requires the command to have a transaction when the connection assigned to the command is in a pending
    如何从vss中分离程序
    String or binary data would be truncated
    the pop3 service failed to retrieve authentication type and cannot continue
    The POP3 service failed to start because
    IIS Error he system cannot find the file specified _找不到页面
    pku2575Jolly Jumpers
    pku2940Wine Trading in Gergovia
    pku3219二项式系数
    pku1029false coin
  • 原文地址:https://www.cnblogs.com/hyhy904/p/10962037.html
Copyright © 2011-2022 走看看