Jackson的使用

Jackson對於Java對象屬性的可見性

Jackson在序列化時會對Java對象中哪些屬性進行序列化呢?主要有如下幾種java

  • 屬性的修飾符爲public
  • 屬性的修飾符爲private, 可是提供public的get方法
  • 對象中沒有此屬性, 可是類中有public的get方法

也就是說序列化時能不可以訪問到此屬性, 反序列化時能不能設置此屬性的值.sql

注:json

  1. 對於第三種狀況, 鍵就是getXXX中的XXX, 值就是get方法的返回值
  2. 對於屬性是boolean類型的, 那麼該屬性的get方法是isXXX. 以下:
    private boolean exist
    public boolean isExist()

固然也能夠使用@JsonIgnore註解來指定忽略那個屬性, 使這個屬性不參與序列化和反序列化.數組

Jackson對於時間的處理

默認狀況下:

  • 對於java.util.Date、java.sql.Date、java.sql.Timestamp這些時間類, 都會序列化成一個long型的時間戳
  • 對於Java8中新的時間類, 則會序列化成一個數組, 格式爲[年, 月, 日, 時, 分, 秒, 毫秒] 或者 [年, 月, 日], 固然要使用新的時間類, 須要加入jsr310模塊, 在初始化時須要註冊時間模塊
    objectMapper.registerModule(new JavaTimeModule());

格式化:

  1. 全局處理

1.1 在初始化ObjectMapper時設置一個格式.
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
此方式對於java.util.Date、java.time.LocalDateTime、java.time.LocalDate(對於新的時間類前提是有註冊過JavaTimeModule模塊)都有效
Date: 2018-10-27 14:30:30
LocalDateTime: 2018-10-27T14:30:30.475
LocalDate: 2018-10-27
LocalTime:14:30:30app

1.2 使用JavaTimeModule(針對JDK8新的時間類)
能夠發現使用第一種方式後對於LocalDateTime的格式化並不完美, 能夠像下面這樣作工具

JavaTimeModule javaTimeModule = new JavaTimeModule();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
objectMapper.registerModule(javaTimeModule);
  1. 局部處理
    對於指定的時間屬性使用@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")註解

一個自定義的JSON工具類

package com.wangtao.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * JSON工具類.
 * Created at 2018/9/30 11:45
 *
 * @author wangtao
 */
public class JSONUtils {

    private static ObjectMapper objectMapper = new ObjectMapper();

    private static final String STANDARD_PATTERN = "yyyy-MM-dd HH:mm:ss";
    private static final String DATE_PATTERN = "yyyy-MM-dd";
    private static final String TIME_PATTERN = "HH:mm:ss";

    private static final Logger LOG = LoggerFactory.getLogger(JSONUtils.class);

    static {

        //設置java.util.Date時間類的序列化以及反序列化的格式
        objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_PATTERN));

        // 初始化JavaTimeModule
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        //處理LocalDateTime
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(STANDARD_PATTERN);
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));

        //處理LocalDate
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));

        //處理LocalTime
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_PATTERN);
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter));

        //註冊時間模塊, 支持支持jsr310, 即新的時間類(java.time包下的時間類)
        objectMapper.registerModule(javaTimeModule);

        // 包含全部字段
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

        // 在序列化一個空對象時時不拋出異常
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

        // 忽略反序列化時在json字符串中存在, 但在java對象中不存在的屬性
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }

    private JSONUtils() {

    }

    /**
     * 將Java對象序列化成一個JSON對象或者JSON數組.
     *
     * @param object Java對象
     * @return 返回一個JSON格式的字符串
     */
    public static String objToJson(Object object) {
        try {
            if (object != null) {
                return objectMapper.writeValueAsString(object);
            }
        } catch (JsonProcessingException e) {
            LOG.error("parse {} to json error!", object, e);
        }
        return null;
    }

    /**
     * 將JSON對象反序列化成一個Java原生對象, 不支持泛型.
     *
     * @param json JSON對象
     * @param cls  Java對象原始類型的class對象
     * @param <T>  Java對象的原始類型
     * @return 返回一個T類型的對象
     */
    public static <T> T jsonToObj(String json, Class<T> cls) {
        try {
            if (json != null && json.length() > 0) {
                return objectMapper.readValue(json, cls);
            }
        } catch (IOException e) {
            LOG.error("parse {} to object error!", json, e);
        }
        return null;
    }

    /**
     * 將JSON反序列化成一個Java對象, 支持泛型.
     * TypeReference是一個抽象類, 用來構造類型
     * 調用方式: 傳入一個TypeReference的匿名實現類便可
     * User user = jsonToObj(json, new TypeReference<User>(){})
     * List<User> users = jsonToObj(json, new TypeReference<List<User>>(){})
     *
     * @param json          JSON對象
     * @param typeReference 類型引用
     * @param <T>           返回值類型
     * @return 返回一個Java對象
     */
    public static <T> T jsonToObj(String json, TypeReference<?> typeReference) {
        try {
            if (json != null && json.length() > 0) {
                return objectMapper.readValue(json, typeReference);
            }
        } catch (Exception e) {
            LOG.error("parse {} to object error!", json, e);
        }
        return null;
    }

    /**
     * 將一個JSON數組反序列化成一個List對象.
     *
     * @param json JSON數組
     * @param cls  Java對象原始類型的class對象
     * @param <T>  Java對象的原始類型
     * @return 返回一個List列表
     */
    public static <T> List<T> jsonToList(String json, Class<T> cls) {
        List<T> list = new ArrayList<>();
        try {
            if (json != null && json.length() > 0) {
                JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
                list = objectMapper.readValue(json, javaType);
            }
        } catch (IOException e) {
            LOG.error("parse {} to object error!", json, e);
        }
        return list;
    }
}
相關文章
相關標籤/搜索