spring中的枚举类型转换

前端所发送的参数本质上是string类型,正常情况下会由框架提供的转换器自动帮我们,直接复制到后端由于接收参数的实体对象或同类型的参数中

但是

当前端传了一个数字代表某种状态,而后端用枚举类型进行接收时,就会发生错误。

此时,可以自定义转换器

当前端以param格式传来数据时

方法一 自定义converter:

复制代码
@Component
//String为前端传来的值
//ItemType为需要转化为的枚举类型的枚举类
public class StringToItemTypeConverter implements Converter<String, ItemType> {
    @Override
    public ItemType convert(String code) {
        //遍历枚举类,若存在对应的值,则返回枚举类型
        ItemType[] values = ItemType.values();
        for (ItemType itemType : values) {
            if (itemType.getCode().equals(Integer.valueOf(code))){
                return itemType;
            }
        }
        throw new IllegalArgumentException("code:"+code+"非法");
    }
}

//即将将前端发来的值,转化为对应的枚举类型

方法二 自定义converter工厂

复制代码
@Component
//BaseEnum为多个枚举类的父接口//工厂可以将String转化为实现BaseEnum接口中子枚举类类
public class StringToBaseEnumConverterFactory implements ConverterFactory<String, BaseEnum> {
    @Override
    public <T extends BaseEnum> Converter<String, T> getConverter(Class<T> targetType) {
        //返回一个Converter
        return new Converter<String, T>() {
            @Override
            public T convert(String code) {
        //还是遍历,但我们并不知道调用此converter时,所需要转换为的目标枚举类
        //则通过targetType反射获取目标枚举类
                T[] enumConstants = targetType.getEnumConstants();
                for (T constant : enumConstants) {
                    if (constant.getCode().equals(Integer.valueOf(code))){
                        return constant;
                    }
                }
                throw new IllegalArgumentException("code:"+code+"非法");
            }
        };
    }
}

//当存在多个枚举类时,并不需要逐一创建对应的converter,而是可通过创建通用converter工厂。当后端用枚举类型进行接收时,会自动调用该转换器

对自定义的转换器进行配置

复制代码
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
    @Autowired
    private StringToItemTypeConverter stringToItemTypeConverter;

    @Autowired
    private StringToBaseEnumConverterFactory stringToBaseEnumConverterFactory;

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(this.stringToItemTypeConverter);
        registry.addConverterFactory(this.stringToBaseEnumConverterFactory);
      }
}

当前端以Json格式传来数据时

public enum ItemType implemts BaseEnum {

//默认转换规则是枚举对象实例(ItemType.APARTMENT)和实例名称("APARTMENT")相互映射

//ItemType.ROOM<->ROOM

//后端发送给前端的json字符串中code并非是我们想要的数字

APARTMENT(1, "公寓"),

ROOM(2, "房间");

//使用使用注解JsonValue,当发送转化时,则会变成

ItemType.ROOM<->code

@JsonValue

private Integer code;

private String name;

ItemType(Integer code, String name) {

this.code = code;

this.name = name;

}

}

MVC和数据库的交互

public enum ItemType implemts BaseEnum {

//正常情况下,数据库中的状态以数字保存,但在mvc中是枚举类型,而以默认的TypeHeandler进行转化时,给后端发去的参数并非是对应的数字,而是

ItemType.ROOM<->ROOM

此时就会报错

APARTMENT(1, "公寓"),

ROOM(2, "房间");

//使用注解EnumValue,当发送转化时,则会变成

ItemType.ROOM<->code

@JsonValue

@EnumValue

private Integer code;

private String name;

ItemType(Integer code, String name) {

this.code = code;

this.name = name;

}

}

BaseEnum

复制代码
public interface BaseEnum {

    Integer getCode();

    String getName();
}
相关推荐
风象南2 分钟前
SpringBoot 自研「轻量级 API 防火墙」:单机内嵌,支持在线配置
后端
刘一说14 分钟前
CentOS 系统 Java 开发测试环境搭建手册
java·linux·运维·服务器·centos
Victor35619 分钟前
Redis(14)Redis的列表(List)类型有哪些常用命令?
后端
Victor35620 分钟前
Redis(15)Redis的集合(Set)类型有哪些常用命令?
后端
卷福同学21 分钟前
来上海三个月,我在马路边上遇到了阿里前同事...
java·后端
bingbingyihao2 小时前
多数据源 Demo
java·springboot
在努力的前端小白7 小时前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
bobz9659 小时前
小语言模型是真正的未来
后端
一叶飘零_sweeeet9 小时前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
DevYK10 小时前
企业级 Agent 开发实战(一) LangGraph 快速入门
后端·llm·agent