前端所发送的参数本质上是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(); }