最近一个springboot项目用到jackson作对象与json互相转换,在此记上。


一.引入依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>


二.工具类:

package com.easy.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * @author wen
 * @apiNote json序列化工具
 * @since 2019/5/31
 */
@Slf4j
public class JacksonUtil {

    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public static final ObjectMapper OBJECT_CLASS_MAPPER = new ObjectMapper();

    static {
        // 对于空的对象转json的时候不抛出错误
        OBJECT_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 禁用遇到未知属性抛出异常
        OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 序列化BigDecimal时不使用科学计数法输出
        OBJECT_MAPPER.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
        // null的属性不序列化
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        OBJECT_MAPPER.setTimeZone(TimeZone.getDefault());
        // 日期和时间格式化
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        OBJECT_MAPPER.registerModule(javaTimeModule);

        // 对于空的对象转json的时候不抛出错误
        OBJECT_CLASS_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 禁用遇到未知属性抛出异常
        OBJECT_CLASS_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 序列化BigDecimal时不使用科学计数法输出
        OBJECT_CLASS_MAPPER.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
        // null的属性不序列化
        OBJECT_CLASS_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        OBJECT_CLASS_MAPPER.setTimeZone(TimeZone.getDefault());
        // 日期和时间格式化
        OBJECT_CLASS_MAPPER.registerModule(javaTimeModule);
        OBJECT_CLASS_MAPPER.activateDefaultTyping(OBJECT_CLASS_MAPPER.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
    }

    /**
     * 序列化对象(转json)
     */
    public static String toJson(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof String) {
            return obj.toString();
        }
        if (obj instanceof Number) {
            return obj.toString();
        }
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("JacksonUtil.toJson-json序列化出错: {}", obj, e);
            return null;
        }
    }

    /**
     * 序列化对象(转json)
     */
    public static String toJson(Object obj, FilterProvider filters) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof String) {
            return obj.toString();
        }
        if (obj instanceof Number) {
            return obj.toString();
        }
        try {
            return OBJECT_MAPPER.writer(filters).writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("JacksonUtil.toJson-json序列化出错: {}", obj, e);
            return null;
        }
    }

    /**
     * 反序列化(json转为Bean)
     */
    public static <T> T parse(String json, Class<T> tClass) {
        if (ValidUtil.isNull(json)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(json, tClass);
        } catch (IOException e) {
            log.error("JacksonUtil.parse-json解析出错: {}", json, e);
            return null;
        }
    }

    /**
     * 反序列化(json转List)
     */
    public static <E> List<E> parseList(String json, Class<E> eClass) {
        return nativeRead(json, List.class, eClass);
    }

    /**
     * 反序列化(json转Map)
     */
    public static <K, V> Map<K, V> parseMap(String json, Class<K> kClass, Class<V> vClass) {
        return nativeRead(json, Map.class, kClass, vClass);
    }

    /**
     * 反序列化(json转LinkedHashMap)
     */
    public static <K, V> LinkedHashMap<K, V> parseLinkedHashMap(String json, Class<K> kClass, Class<V> vClass) {
        return nativeRead(json, LinkedHashMap.class, kClass, vClass);
    }

    /**
     * json转复杂对象
     */
    public static <T> T nativeRead(String json, TypeReference<T> type) {
        if (ValidUtil.isNull(json)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(json, type);
        } catch (IOException e) {
            log.error("JacksonUtil.nativeRead-json解析出错: {}", json, e);
            return null;
        }
    }

    /**
     * @param json         json字符串
     * @param javaClazz    需要转换的java对象类型,
     *                     例如:List.class, ArrayList.class, Map.class, HashMap.class, LinkedHashMap.class
     * @param genericClazz 泛型类型
     * @return T
     * @author wen
     * @since 2021/1/20
     */
    public static <T> T nativeRead(String json, Class<?> javaClazz, Class<?>... genericClazz) {
        if (ValidUtil.isNull(json)) {
            return null;
        }
        try {
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(javaClazz, genericClazz);
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (Exception e) {
            log.error("JacksonUtil.nativeRead-json解析出错: ", e);
            return null;
        }
    }

    /**
     * 将对象序列化为带有class属性的json字符串
     */
    public static String toObjJson(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof String) {
            return obj.toString();
        }
        if (obj instanceof Number) {
            return obj.toString();
        }
        try {
            return OBJECT_CLASS_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("JacksonUtil.toObjJson-json序列化出错: {}", obj, e);
            return null;
        }
    }

    /**
     * 将带有class属性的json字符串转为对应对象
     */
    public static Object parseObj(String json) {
        if (ValidUtil.isNull(json)) {
            return null;
        }
        try {
            if (json.startsWith("{") || json.startsWith("[")) {
                return OBJECT_CLASS_MAPPER.readValue(json, Object.class);
            }
            return json;
        } catch (IOException e) {
            log.error("JacksonUtil.parseObj-json解析出错: {}", json, e);
            return null;
        }
    }

    /**
     * 字符串转为指定对象
     */
    public static Object parseClazz(String targetStr, Class<?> clazz) {
        if (clazz == String.class) {
            return targetStr;
        }
        if (ValidUtil.isNull(targetStr)) {
            return null;
        }
        if (targetStr.startsWith("{")) {
            return parse(targetStr, clazz);
        }
        if (targetStr.startsWith("[")) {
            return parseList(targetStr, clazz);
        }
        if (clazz == Integer.class) {
            return Integer.valueOf(targetStr);
        }
        if (clazz == Long.class) {
            return Long.valueOf(targetStr);
        }
        if (clazz == BigDecimal.class) {
            return new BigDecimal(targetStr);
        }
        if (clazz == Boolean.class) {
            return Boolean.valueOf(targetStr);
        }
        if (clazz == Double.class) {
            return Double.valueOf(targetStr);
        }
        if (clazz == Float.class) {
            return Float.valueOf(targetStr);
        }
        if (clazz == Short.class) {
            return Short.valueOf(targetStr);
        }
        if (clazz == Byte.class) {
            return Byte.valueOf(targetStr);
        }
        return null;
    }

    /**
     * 对象转map
     */
    public static Map<String, Object> obj2Map(Object object) {
        return OBJECT_MAPPER.convertValue(object, new TypeReference<>() {
        });
    }

    /**
     * 对象转其他
     */
    public static <T> T obj2Val(Object object) {
        return OBJECT_MAPPER.convertValue(object, new TypeReference<T>() {
        });
    }

    public static JsonNode readTree(String json) {
        if (ValidUtil.isNull(json)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readTree(json);
        } catch (IOException e) {
            log.error("JacksonUtil.readTree-json解析出错: {}", json, e);
            return null;
        }
    }

    /**
     * 序列化
     */
    public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException {
            if (value != null) {
                String timestamp = String.valueOf(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
                gen.writeNumber(timestamp);
            }
        }
    }

    /**
     * 反序列化
     */
    public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext)
                throws IOException {
            long timestamp = p.getValueAsLong();
            if (timestamp > 0) {
                return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
            } else {
                return null;
            }
        }
    }

}