SpringBoot 枚举类型的自动转换的实现

网友投稿 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 > Converter getConverter(Class targetType) {

return new StringToEnum<>(targetType);

}

public static class StringToEnum> implements Converter {

private final Class targetType;

public StringToEnum(Class targetType) {

this.targetType = targetType;

}

@Override

public T convert(String source) {

if (!StringUtils.hasText(source)) {

return null;

}

return (T) EnumConvertFactory.getEnum(this.targetType, source);

}

}

public static > T getEnum(Class targetType, String source) {

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> implements ContextualDeserializer vJjgo{

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小时内删除侵权内容。

上一篇:SpringBoot后端上传文件类型检测方式
下一篇:SpringBoot如何通过配置文件(yml,properties)限制文件上传大小
相关文章

 发表评论

暂时没有评论,来抢沙发吧~