springboot中默认使用jackson,且实现了很多参数转换器,其中就有EnumToStringConverter和StringToEnumConverterFactory,用于字符串和枚举的互转。但是是根据枚举名称互转。

  1. 空属性我不希望转成json字符串
  2. 日期对象我希望按照指定格式转换
  3. 我存在多个枚举,类似public enum ChannelWayEnum { Bluetooth(0, "蓝牙"), NB(1, "NB-IOT"), G4(2, "自建4G"), Ali(3, "ali-4G");},用默认转换器无法转换。需要自定义转换。
  1. 覆盖默认注入的ObjectMapper,自己实现objectMapper,可设置忽略null字段
  2. 自定义针对日期对象的Converter
  3. 枚举需要实现接口IEnum,然后自定义针对IEnum接口的转换器
  1. 注入ObjectMapper
@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;     } } 
  1. 日期对象的转换
@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);     } } 
  1. 接口
/**  * 枚举都要继承此接口,  * @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());     } } 
  1. 枚举的转换器
/**  * 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();     } } 

以上代码比较简单,就没有写注释,有问题请留言。