Jackson 序列化和反序列化


博客地址:https://www.moonxy.com

一、前言

Jackson 功能很強大,既能滿足簡單的序列化和反序列化操作,也能實現復雜的、個性化的序列化和反序列化操作。到目前為止,Jackson 的序列化和反序列化性能都非常優秀,已經是國內外大部分 JSON 相關編程的首選工具。

Jackson從 2.0 開始改用新的包名 fasterxml,1.x 版本的包名是 codehaus。除了包名不同,他們的 Maven artifact id 也不同。1.x 版本現在只提供 bug-fix,而 2.x 版本還在不斷開發和發布中。如果是新項目,建議直接用 2x,即 fasterxml jackson。

二、Jackson 操作

2.1 ObjectMapper 類

ObjectMapper 類是 Jackson 庫的主要類,它能夠實現 Java 對象與 JSON 數據之間的序列化和反序列化。

package lucene.file.search.tester;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Jackson從2.0開始改用新的包名fasterxml,1.x版本的包名是codehaus。除了包名不同,他們的Maven artifact id也不同。
 * 1.x版本現在只提供bug-fix,而2.x版本還在不斷開發和發布中。如果是新項目,建議直接用2x,即fasterxml jackson        
 * @author Administrator
 * jackson-core:核心包
 * jackson-annotations:注解包
 * jackson-databind:數據綁定包
 */
public class JacksonUtil {
    
    private static ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * JSON字符串反序列化成Java對象
     * @param json
     * @return
     */
    public static UserEntity databind(String json){
        UserEntity user = null;
        try {
            user = objectMapper.readValue(json, UserEntity.class);
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return user;
    }
    
    /**
     * Java對象序列化成JSON字符串
     * @param user
     * @return
     */
    public static String custom(UserEntity user){
        String json = null;
        try {
            json = objectMapper.writeValueAsString(user);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return json;
    }
    
    /**
     * Jackson提供了JavaType,用來指明集合類型和泛型
     * @param collectonClass
     * @param elementClasses
     * @return
     */
    public static JavaType getCollectionType(Class<?> collectonClass, Class<?>... elementClasses){
        return objectMapper.getTypeFactory().constructParametricType(collectonClass, elementClasses);
    }
    
    /**
     * 集合的反序列化
     * @param jsonArray
     * @return
     */
    public static List<UserEntity> databinds(String jsonArray){
        JavaType type = getCollectionType(List.class, UserEntity.class);
        List<UserEntity> list = null;
        try {
            list = objectMapper.readValue(jsonArray, type);
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
    
    public static void main(String[] args) throws JsonProcessingException {
        //JSON字符串反序列化成Java對象
        String json = "{\"name\":\"Rain\",\"id\":4405,\"age\":28,\"createDate\":\"2018-01-25 12:17:22\",\"phone\":\"13891701101\"}";
        UserEntity user = databind(json);
        System.out.println(user.toString());
        
        //Java對象序列化成JSON字符串
        //UserEntity user = new UserEntity();
        user.setId(10086L);
        user.setName("Bob");
        user.setAge(18);
        user.setCreateDate(new Date());
        System.out.println(custom(user));
        
        //集合的反序列化和序列化
        String jsonArray = "[{\"name\":\"Rain\",\"id\":4405,\"age\":28,\"createDate\":\"2018-01-25 12:17:22\",\"phone\":\"13891701102\"},"
                + "{\"name\":\"Jim\",\"id\":4406,\"age\":26,\"createDate\":\"2018-01-25 12:17:22\",\"phone\":\"13891701103\"}]";
        
        List<UserEntity> userList = databinds(jsonArray);
        for (UserEntity userEntity : userList) {
            System.out.println(userEntity.toString());
        }
        
        //集合的序列化
        System.out.println(objectMapper.writeValueAsString(userList));

    }

}

2.2 Jackson 常用注解

Jackson 包含了很多注解,用來個性化序列化和反序列化操作,主要包含如下注解。

@JsonProperty,作用在屬性上,用來為 JSON Key 指定一個別名;

@JsonIgnore,作用在屬性上,用來忽略此屬性;

@JsonIgnoreProperties,忽略一組屬性,作用在類上,比如 @JsonIgnorePropertiess({"id","phone"});

@JsonAnySetter,標記在某個方法上,此方法接收 Key、Value,用於 Jackson 在反序列化過程中,未找到的對應屬性都調用此方法。通常這個方法用一個 Map 來實現;

@JsonAnyGetter,此注解標注在一個返回 Map 的方法上,Jackson 會取出 Map中的每一個值進行序列化;

@JsonFormat,用於日期的格式化,如:

@JsonFormat(pattern="yyyy-MM-dd HH-mm-ss")
private Date createDate;

@JsonNaming,用於指定一個命名策略,作用於類或者屬性上,類似 @JsonProperty,但是會自動命名。Jackson 自帶了多種命名策略,你也可以實現自己的命名策略,比如輸入的 Key 由 Java 命名方式轉換為下划線命名方式:userName 轉換為 user-name;

@JsonSerialize,指定一個實現類來自定義序列化。類必須實現 JsonSerializer 接口;

@JsonDeserialize,用戶自定義反序列化,同 @JsonSerialize,類需要實現 JsonDeserialize 接口;

@JsonView,作用在類或者屬性上,用來定義一個序列化組。Spring MVC 的 Controller 方法可以使用同樣的 @JsonView 來序列化屬於這一組的配置。

觀察者模式又叫做發布訂閱模式,它定義了一種一對多的關系,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象的狀態發生改變時就會通知所有觀察着對象。它是由兩類對象組成,主題和觀察者,主題負責發布事件,同時觀察者通過訂閱這些事件來觀察該主體,發布者和訂閱者是完全解耦的,彼此不知道對方的存在,兩者僅僅共享一個自定義事件的名稱。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM