springboot中默认使用jackson,且实现了很多参数转换器,其中就有EnumToStringConverter和StringToEnumConverterFactory,用于字符串和枚举的互转。但是是根据枚举名称互转。
public enum ChannelWayEnum { Bluetooth(0, "蓝牙"), NB(1, "NB-IOT"), G4(2, "自建4G"), Ali(3, "ali-4G");
},用默认转换器无法转换。需要自定义转换。@Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { return createObjectMapper(); } private ObjectMapper createObjectMapper(){ ObjectMapper objectMapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); /** * 序列化:对象=>jsonString */ simpleModule.addSerializer(WashEnum.class, new WashEnumSerializer()); simpleModule.addSerializer(IEnum.class, new EnumSerializer()); simpleModule.addSerializer(Date.class, new DateSerializer()); simpleModule.addSerializer(Boolean.class, new BooleanSerializer()); //忽略null字段 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); /** * 反序列化:jsonString=>对象 */ //允许json属性名不使用双引号 objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); //忽略不存在字段 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); simpleModule.addDeserializer(String.class, new StringDeserializer()); simpleModule.addDeserializer(Date.class, new DateDeserializer()); simpleModule.addDeserializer(WashEnum.class, new WashEnumDeserializer()); simpleModule.addDeserializer(Enum.class, new EnumDeserializer());//反序列化枚举, simpleModule.addDeserializer(Boolean.class, new BooleanDeserializer()); objectMapper.registerModule(simpleModule); return objectMapper; } }
@JsonComponent public class DateDeserializer extends JsonDeserializer<Date> implements Converter<String, Date> { @Override public Date deserialize(JsonParser p, DeserializationContext ctxt) { try { return convert(p.getText()); } catch (IOException e) { e.printStackTrace(); } return null; } @Override public Date convert(String source) { if (StringUtil.isBlank(source)) { return null; } return TimeUtil.toDate(TimeUtil.str2Time(source, TimeFormat.DEFAULT)); } } @JsonComponent public class DateSerializer extends JsonSerializer<Date> implements Converter<Date,String> { @Override public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers){ try { gen.writeString(convert(value)); } catch (IOException e) { e.printStackTrace(); } } @Override public String convert(Date source) { return TimeUtil.time2Str(TimeUtil.date2Time(source),TimeFormat.DEFAULT); } }
/** * 枚举都要继承此接口, * @param <V> 枚举实际值的数据类型 */ public interface IEnum<V> { //枚举实际值 V getValue(); static<T extends IEnum> T getBean(String value,Class<T> tClass){ if (StringUtil.isBlank(value)){ return null; } for (T enumObj : tClass.getEnumConstants()) { if (value.equals(enumObj.getValue().toString())) { return enumObj; } } return null; } default String getStr(){ return String.valueOf(getValue()); } }
/** * json=>对象 */ @JsonComponent public class EnumDeserializer<T extends IEnum> extends JsonDeserializer<T> implements ContextualDeserializer{ private Class<T> targetClass = null; public EnumDeserializer() { } public EnumDeserializer(Class<T> targetClass) { this.targetClass = targetClass; } @Override public T deserialize(JsonParser p, DeserializationContext ctxt) { // if(targetClass!=null&&IEnum.class.isAssignableFrom(targetClass)){ try { return IEnum.getBean(p.getText(),targetClass); } catch (IOException e) { e.printStackTrace(); } // } return null; } @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) { Class<T> targetClass = (Class<T>) ctxt.getContextualType().getRawClass(); return new EnumDeserializer(targetClass); } } /** * 序列化,将enum枚举转为json * @author chenzy * @since 2019.12.19 */ @JsonComponent public class EnumSerializer<T extends IEnum> extends JsonSerializer<T> { @Override public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException { Optional<T> data = Optional.of(value); if (data.isPresent()) {//非空 gen.writeObject(data.get().getValue()); } else { // gen.writeString(""); } } }
下面才是真正的转换器
/** * IEnum=>str */ @Component public class Enum2StrConverter<T extends IEnum<?>> implements ConditionalConverter,Converter<T, String>{ private final ConversionService conversionService; protected Enum2StrConverter(ConversionService conversionService) { this.conversionService = conversionService; } @Override public String convert(T source) { return source.getStr(); } @Override public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { for (Class<?> interfaceType : ClassUtils.getAllInterfacesForClassAsSet(sourceType.getType())) { if (this.conversionService.canConvert(TypeDescriptor.valueOf(interfaceType), targetType)) { return false; } } return true; } } /** * str=>IEnum */ @Component public class Str2EnumConverte implements ConverterFactory<String, IEnum> { @Override public <T extends IEnum> Converter<String, T> getConverter(Class<T> targetType) { return new Str2Enum(targetType); } private static class Str2Enum<T extends IEnum> implements Converter<String, T> { private final Class<T> enumType; public Str2Enum(Class<T> enumType) { this.enumType = enumType; } @Override public T convert(String source) { if (StringUtil.isBlank(source)) { return null; } return IEnum.getBean(source,enumType); } } } /** * @author chenzy * @since 2020-12-02 */ @Configuration public class JacksonConfig implements WebMvcConfigurer { @Autowired private Str2EnumConverte str2EnumConverte; @Override public void addFormatters(FormatterRegistry registry) { registry.addConverterFactory(str2EnumConverte); } @Bean public ObjectMapper objectMapper() { return JsonUtil.getObjectMapper(); } }
以上代码比较简单,就没有写注释,有问题请留言。
下一个:UML——顺序图