Java设计模式之外观模式示例详解
446
2022-08-18
SpringBoot 枚举类型的自动转换的实现
目录1、请求头接收参数2、请求体接收3、添加自定义枚举序列化
需求:一般我们在数据库都会定义数值型的枚举常量,不管是序列化还是反序列化都是需要我们手动去转换成枚举类型的,既然这样我们能不能让它们自动转换呢?接下来我们就来尝试一下:
首先解决如何接收枚举类型。
枚举父类
/**
* @author rookie
*/
public interface IEnum
/**
* 获取值
* @return 值
*/
T getValue();
}
1、请求头接收参数
添加Convert
@Component
public class EnumConvertFactory implements ConverterFactory
@Override
public
return new StringToEnum<>(targetType);
}
public static class StringToEnum
private final Class
public StringToEnum(Class
this.targetType = targetType;
}
@Override
public T convert(String source) {
if (!StringUtils.hasText(source)) {
return null;
}
return (T) EnumConvertFactory.getEnum(this.targetType, source);
}
}
public static
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
/**
* 测试
*/
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
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
@Override
public void serialize(IEnum iEnum, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(iEnum.getName());
}
}
注册序列化处理器
@Component
public class BeanLoadProcess implements SmvJjgoartInitializingSingleton {
@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
好了这样就行了。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~