jackson在springboot中的的用法

springboot调用的反序列化-与序列化

/**
 * 反序列化
 * json->枚举
 * @author chenzy
 * @date 2019.12.18
 */
public class EnumConvertFactory  implements ConverterFactory<String, IEnum> {
    @Override
    public <EN extends IEnum> Converter<String, EN> getConverter(Class<EN> targetType) {
        return new StringToIEum<>(targetType);
    }
    private class StringToIEum<EN extends IEnum> implements Converter<String, EN> {
        Class<EN> targerType;
        StringToIEum(Class<EN> targerType) {
            this.targerType = targerType;
        }

        @Override
        public EN convert(String source) {
            if (StringUtils.isEmpty(source)) {
                return null;
            }
            return getIEnum(this.targerType, source);
        }
    }
    private <EN extends IEnum> EN getIEnum(Class<EN> targerType, String source) {
        for (EN enumObj : targerType.getEnumConstants()) {
            if (source.equals(enumObj.getValue().toString())) {
                return enumObj;
            }
        }
        return null;
    }
}

/**
 * 配置 使用springboot的json-model转换功能
 * @author chenzy
 * @2019.12.25
 */
@Configuration
public class JsonConfig implements WebMvcConfigurer {
    /***
     * 请求参数转换为枚举.
     * springboot自动转换时使用。
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(new EnumConvertFactory());
    }
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomizer() {
        return m -> {
            m.serializerByType(IEnum.class, new EnumSerializer());
//            m.deserializerByType(Enum.class,new EnumDeserializer());//没有作用
            m.serializationInclusion(JsonInclude.Include.NON_NULL);//过滤null
//            m.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
        };
    }
}

枚举需要实现IEnum接口:

public interface IEnum<T> {
    T getValue();
}

序列化:

/**
 * 序列化,将enum枚举转为json
 * @author chenzy
 * @date 2019.12.19
 */
public class EnumSerializer extends JsonSerializer<IEnum> {
    @Override
    public void serialize(IEnum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        Optional<IEnum> data = Optional.of(value);
        if (data.isPresent()) {

            IEnum iEnum = data.get();
            gen.writeObject(iEnum.getValue());

            /*Class enumClass = iEnum.getClass();
            String key = null;
            for (Field field : enumClass.getDeclaredFields()) {
                if (field.isAnnotationPresent(JsonProperty.class)) {
                    key = field.getAnnotation(JsonProperty.class).value();
                }
            }
            gen.writeStartObject();
            gen.writeStringField(key,iEnum.get().toString());
            gen.writeEndObject();*/
        } else {
            gen.writeString("");
        }


    }

}

jackson反序列的两种方式:json转对象

  1. 实现Converter接口
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;
/**
 * 反序列化时使用:json转enum。一定要实现此类,在构造方法中为classType赋值
 * @author chenzy
 * @date 2019.12.19
 * @param <EN> 具体的枚举类型
 */
public abstract class EnumConvert<V,EN extends IEnum> implements Converter<V,EN> {

    @Override
    public JavaType getInputType(TypeFactory typeFactory) {
        return typeFactory.constructType(String.class);
    }

    @Override
    public JavaType getOutputType(TypeFactory typeFactory) {
        if (enType ==null){
            try {
                throw new Exception(":未在实现类的构造方法中为classType赋值");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return typeFactory.constructType(enType);
    }

    @Override
    public EN convert(V value) {
        if (value==null){
            return null;
        }
        for (EN enumObj : enType.getEnumConstants()) {
            if (value.toString().equals(enumObj.getValue().toString())) {
                return enumObj;
            }
        }
        return null;
    }
    private Class<EN> enType;
    protected void setEnType(Class<EN> enType){
        this.enType = enType;
    }
}

枚举:


/**
 * 响应码级别
 *
 * @author chenzy
 * @date 2019.12.16
 */
@JsonDeserialize(converter = ResCodeLevelEnum.ResCodeLevelEnumConvert.class)
public enum ResCodeLevelEnum implements IEnum<Integer> {
    Lev1(1, "一级故障"), Lev2(2, "二级故障"), Lev3(3, "三级故障"), SysProtect(4, "系统保护"), Debug(5, "开发时异常"), Warn(6, "提醒级"), Info(7, "提示"), Normal(8, "正常"),
    ;

    private Integer id;
    private String msg;

    ResCodeLevelEnum(Integer level, String msg) {
        this.id = level;
        this.msg = msg;
    }

    @Override
    public String toString() {
        return getValue().toString();
    }

    @Override
    public Integer getValue() {
        return this.id;
    }

    protected class ResCodeLevelEnumConvert extends EnumConvert<Integer, ResCodeLevelEnum> {
        public ResCodeLevelEnumConvert() {
            setEnType(ResCodeLevelEnum.class);
        }
    }
}

调用

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.readValue(jsonStr, targetClass);
  1. EnumDeserializer
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(Enum.class,new EnumDeserializer());//反序列化枚举,
objectMapper.registerModule(simpleModule);
objectMapper.readValue(jsonStr, targetClass);
package cn.lexiaotongvip.www.config.jsonConfig;
import cn.lexiaotongvip.www.util.EnumUtil;
import com.baomidou.mybatisplus.core.enums.IEnum;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;

import java.io.IOException;

/**
 * json=>对象
 */
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 {
                String value = p.getText();
                return EnumUtil.getIEnum(targetClass,value);
            } 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);
    }
}

public class EnumUtil {
    private EnumUtil(){}
    public static  <EN extends IEnum> EN getIEnum(Class<EN> targerType, String source) {
        for (EN enumObj : targerType.getEnumConstants()) {
            if (source.equals(enumObj.getValue().toString())) {
                return enumObj;
            }
        }
        return null;
    }
}

版权声明:本文为dimandsun原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。