spring cloud jackson 枚举json互转 枚举json序列化/反序列化

1、先定义一个枚举基类BaseEnum

public interface BaseEnum {
    
    default String getCode() {
        return this.name();
    }

    String getDisplayName();

    static <E extends Enum<E>> BaseEnum valueOf(String enumCode,Class<E> clazz) {
        BaseEnum enumm = (BaseEnum) Enum.valueOf(clazz, enumCode);
        return enumm;
    }

    String name();

} 

 

2、定义自己的枚举并且实现 BaseEnum

/**
 * 通用状态,所有跟状态相关的都按照这个定义
 * @author Binz
 * @date 2019-05-14 11:28:25
 */
public enum CommonStatus implements BaseEnum{
    ENABLED("启用"),
    DISABLED("停用"),
    DELETE("删除")
    ;
    
    CommonStatus(String displayName){
        this.displayName = displayName;
    }
    
    private String displayName;

    @Override
    public String getDisplayName() {
        return displayName;
    }
}

 

3、自定义枚举转换器-序列化

 

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
 * 用于BaseEum的子类解析成json格式,一般在api中注入此解析器
 * @author  Binz
 * 2019-05-27 11:29:02
 */
public class BaseEnumSerializer extends JsonSerializer<BaseEnum>{

    @Override
    public void serialize(BaseEnum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        Map<String,String> map = new HashMap<>();
        map.put("code", value.getCode());
        map.put("displayName", value.getDisplayName());
        gen.writeObject(map);
    }

}

 

 

 4、自定义枚举转换器-反序列化

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;


/**
 * 接收BaseEnum反序列化
 * 2019-07-12 16:49
 */
@SuppressWarnings("rawtypes")
public class BaseEnumDeserializer extends JsonDeserializer<BaseEnum>{

    private Class<Enum> clazz = null;
    public BaseEnumDeserializer(Class<Enum> clazz) {
        this.clazz = clazz;
    }

    @SuppressWarnings("unchecked")
    @Override
    public BaseEnum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String asText = null;
        if(node.getNodeType() == JsonNodeType.STRING) {
            asText = node.asText();
        }else{
            asText = node.get("code").asText();
        }
        BaseEnum valueOf = null;
        if(StringUtil.isNotBlank(asText)){
            valueOf = BaseEnum.valueOf(asText, clazz);
        }
        return valueOf;
    }

}

5、注册反序列化和序列化

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.filter.AssignableTypeFilter;

import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.xxx.core.base.BaseEnum;
import com.xxx.core.base.BaseException;
import com.xxx.core.config.convert.BaseEnumDeserializer;
import com.xxx.core.config.convert.BaseEnumSerializer;

@Configuration
public class BaseEnumConfigure {
    
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer enumCustomizer() throws BaseException{
        
        return jacksonObjectMapperBuilder -> {
          //自定义序列化器注入
          Map<Class<?>, JsonSerializer<?>> serializers = new LinkedHashMap<>();
          serializers.put(BaseEnum.class, new BaseEnumSerializer());
          jacksonObjectMapperBuilder.serializersByType(serializers);
          
          
          ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
          provider.addIncludeFilter(new AssignableTypeFilter(BaseEnum.class));
          //扫描枚举所在的包
          Map<Class<?>, JsonDeserializer<?>> deserializers = new LinkedHashMap<>();
          Set<BeanDefinition> components = provider.findCandidateComponents("com.xxx");
          for (BeanDefinition component : components) {
                try {
                    Class<?> cls = Class.forName(component.getBeanClassName());
                    if(cls.isEnum()) {
                        @SuppressWarnings({ "rawtypes", "unchecked" })
                        Class<Enum> baseEnumClass = (Class<Enum>) cls;
                        //自定义反序列化器注入
                        deserializers.put(cls, new BaseEnumDeserializer(baseEnumClass));
                    }
                } catch (ClassNotFoundException e) {
                   throw new BaseException(e.getMessage());
                }
          }
          jacksonObjectMapperBuilder.deserializersByType(deserializers);
          
      };
    }

}

 

然后spring cloud之间交互的实体类中的枚举就可以自动正常转换了,缺少的引用根据自身项目更改

 

分享一个淘宝、京东、拼多多、饿了么、美团、抖音等等买东西后真实返钱小技巧,

打车、外卖领券,充值话费95折好像也可以

使用教程用微信扫下方二维码查看详细说明

 

posted @ 2018-06-13 17:41  Binz  阅读(9572)  评论(1编辑  收藏  举报