Jackson的基本用法與拓展

目錄

  1、先搞兩個測試須要使用的類java

  2、簡單操做:obj與json互轉json

    2.一、對象轉json字符串數組

    2.二、json字符串轉對象app

3、拓展需求測試

  3.一、對象轉json時,忽略某個字段spa

    3.二、對象轉json時,自定義json中的屬性名xml

    3.三、對象轉json時,忽略對象中爲null或者""的屬性對象

    3.四、json轉對象時,忽略json中未知的屬性blog

    3.五、對象轉json時,生成格式化的json字符串字符串

 

 

 

 

 

 

 

 

 

 

 

1、先搞兩個測試須要使用的類

  分別是Staff(員工)和Department(部門)

package cn.ganlixin.demo;

import lombok.Data;

@Data
public class Department {

    private String depName;
    private String addr;
    private String superior;
}

  

package cn.ganlixin.demo;

import lombok.Data;

import java.util.List;
import java.util.Map;

@Data
public class Staff {
    private int id;
    private String name;
    private boolean isAdult;
    private List<String> languages;
    private Map<String, Object> scores;
    private Department department;
}

  

2、簡單操做:obj與json互轉

2.一、對象轉json字符串

  核心代碼段

ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(Object obj);
// Object就是須要序列化(轉換爲json字符串的對象)

  

  示例

/**
 * 對象  轉爲  json字符串
 */
@Test
public void test1() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();

    List<String> languages = new ArrayList<>();
    languages.add("Java");
    languages.add("PHP");
    languages.add("Python");
    String languagesJsonStr = mapper.writeValueAsString(languages);
    System.out.println(languagesJsonStr);
    // ["Java","PHP","Python"]

    Map<String, Object> scores = new HashMap<>();
    scores.put("math", 59);
    scores.put("english", 58);
    String scoresJsonStr = mapper.writeValueAsString(scores);
    System.out.println(scoresJsonStr);
    // {"english":58,"math":59}

    Department department = new Department();
    department.setDepName("QA");
    department.setAddr("beijing");
    department.setSuperior("小強");
    String departmentJsonStr = mapper.writeValueAsString(department);
    System.out.println(departmentJsonStr);
    // {"depName":"QA","addr":"beijing","superior":"小強"}
}

  

2.二、json字符串轉對象

  核心代碼

ObjectMapper mapper = new ObjectMapper();
Staff staff = mapper.readValue(jsonStr, Staff.class); 
// 表示將json字符串的內容轉換爲Staff類的對象

  

  示例:

/**
 * 將json字符串轉換爲對象
 */
@Test
public void test2() throws IOException {
    ObjectMapper mapper = new ObjectMapper();

    String languageJsonStr = "[\"Java\",\"PHP\",\"Python\"]";
    final List languages = mapper.readValue(languageJsonStr, List.class);
    System.out.println(languages);
    // [Java, PHP, Python]

    String scoresJsonStr = "{\"english\":58,\"math\":59}";
    Map<String, Object> scores = mapper.readValue(scoresJsonStr, Map.class);
    System.out.println(scores);
    // {english=58, math=59}

    String departmentJsonStr = "{\"depName\":\"QA\",\"addr\":\"beijing\",\"superior\":\"小強\"}";
    final Department department = mapper.readValue(departmentJsonStr, Department.class);
    System.out.println(department);
    // Department(depName=QA, addr=beijing, superior=小強)
}

  

3、拓展需求

3.一、對象轉json時,忽略某個字段

  有些場景中,某些字段在序列化爲json的時候,應該省略掉,好比一個員工的工資,某個用戶的密碼.....

  案例:假設有一個department對象,在轉爲json時,superior(上級)這個字段不能出如今轉換後的json中

  方案1:在不須要參與json序列化的字段前增長@JsonIgnore註解便可

@Data
public class Department {

    private String depName;
    private String addr;

    @JsonIgnore   // 加了@JsonIgnor字段後,superior字段將不參與json序列化
    private String superior;
}

  

   方案2:在類上面使用@JsonIgnoreProperties({"field1", "field2"})來指定哪些字段不參與json序列化

@Data
@JsonIgnoreProperties({"superior"}) 
// 在@JsonIgnoreProperties註解中指定不參與json序列化的字段便可(接收字符串數組)
public class Department {

    private String depName;
    private String addr;
    private String superior;
}

  

  測試

/**
 * 對象轉json時,忽略某個字段
 */
@Test
public void test3() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();

    Department department = new Department();
    department.setDepName("QA");
    department.setAddr("beijing");
    department.setSuperior("小強");

    final String departmentJsonStr = mapper.writeValueAsString(department);
    System.out.println(departmentJsonStr);
    // {"depName":"QA","addr":"beijing"}
}

  

3.二、對象與json互轉時,自定義json中的屬性名

  常常會碰到咱們的模型類中定義的屬性名稱,與外部傳入的json字符串中的名稱不相同的狀況,好比Department類中的superior屬性,接收到外部系統傳過來的json字符串中,對應upLevel字段。

  在序列化時(obj->json)和反序列化時(json->obj)都須要解決上面superior到upLevel的對應問題,Jackson中提供了一個@JsonProperty註解來解決這個問題

@Data
public class Department {
    private String depName;
    private String addr;

    @JsonProperty("upLevel")
    // 指定序列化與反序列化時,superior屬性對應的名稱:序列化時,superior對應到upLevel屬性,反序列化時,upLevel對應到superior屬性
    private String superior;
}

  

  示例:

/**
 * 對象與json互轉時,自定義對應名稱
 */
@Test
public void test4() throws IOException {
    ObjectMapper mapper = new ObjectMapper();

    Department department1 = new Department();
    department1.setDepName("QA");
    department1.setAddr("beijing");
    department1.setSuperior("小強");

    // 對象序列化爲json字符串,注意superior屬性轉json時會變爲upLevel
    String departmentJsonStr = mapper.writeValueAsString(department1);
    System.out.println(departmentJsonStr);
    // {"depName":"QA","addr":"beijing","upLevel":"小強"}

    // 利用上面序列化的字符串,反序列爲對象,upLevel字段會對應到Department對象的superior屬性
    Department department2 = mapper.readValue(departmentJsonStr, Department.class);
    System.out.println(department2);
    // Department(depName=QA, addr=beijing, superior=小強) 
}

  

 3.三、對象轉json時,忽略對象中爲null或者""的屬性

  這個需求是這樣的,對象中,有的屬性值是null或者空字符串,此時,咱們不但願轉換後的json字符串中包含該屬性值爲null或者空字符串的字段。

  好比Department類中的superior屬性,對於老闆來講,沒有上級,則superior的值爲null或者"",此時但願序列化後的json字符串省略superior字段(這與前面的省略某個字段不一樣)。

  Jackson在將對象序列化爲json字符串時,默認是在類級別添加了@JsonInclude(JsonInclude.Include.ALWAYS)註解,表示默認將對象的全部字段都序列化(即便屬性值爲null或者空字符串)。

  要實現忽略對象中屬性值爲null或者""的屬性值,能夠這樣作:

  方案1:

    @JsonInclude(JsonInclude.Include.NON_NULL)  能夠加在指定的字段前(局部),也能夠加在類級別上(全局),當屬性值不爲null的時候纔會參加序列化

    @JsonInclude(JsonInclude.Include.NON_EMPTY) 能夠加在指定的字段前(局部),也能夠加在類級別上(全局),當設置屬性值爲null或者""的時候,該屬性不會參加序列化;

    注意,對於上面兩個註解,若是類中聲明該屬性有默認值,即便沒有爲該屬性設置屬性值,那麼該屬性仍舊會參加序列化。

@Data
public class Department {
    private String depName;
    private String addr;

    @JsonInclude(JsonInclude.Include.NON_NULL) // 加在指定的字段前,當屬性值不爲null的時候纔會參加序列化
    private String superior;
}

  

  方案2:

    方案1使用於要序列化的類數量很少的狀況,若是要進行序列化的類很是多,而且都須要忽略屬性值爲null或者""的屬性,那麼對每個類進行設置@JsonInclude(xxxx)也是很麻煩的,這個時候,咱們能夠從ObjectMapper上進行配置,使用配置後的ObjectMapper,那麼在序列化的時候,自動回忽略值爲null或者""的屬性值。 

/**
 * 全局設置對象轉json時忽略值爲null或者""的屬性
 */
@Test
public void test7() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    // 設置忽略null和""的屬性值,這裏的Include與方案1的一致
    mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

    Department department1 = new Department();
    department1.setDepName("QA");
    department1.setAddr("");
    department1.setSuperior(null);

    String depJsonStr = mapper.writeValueAsString(department1);
    System.out.println(depJsonStr);
    // {"depName":"QA"}
}

 

3.四、json轉對象時,忽略json中未知的屬性

  這個場景是指,json中有一個字段,在類中找很少與之對應的屬性,此時若是強請轉換爲指定類,那麼就會報錯

@Test
public void test8() throws IOException {
    // 注意,json串中多了age字段,而Department類中並沒有該屬性(且無屬性與之對應,好比使用@JsonProperty進行設置)
    String json = "{\"depName\":\"QA\",\"addr\":\"beijing\", \"age\":99}";

    ObjectMapper mapper = new ObjectMapper();
    final Department department = mapper.readValue(json, Department.class);
    System.out.println(department);
}

  上面的運行時會報錯:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "age" (class cn.ganlixin.demo.Department), not marked as ignorable....

  這個狀況,能夠經過設置mapper來解決問題

/**
 * 忽略json中未知的字段名
 */
@Test
public void test9() throws IOException {
    String json = "{\"depName\":\"QA\",\"addr\":\"beijing\", \"age\":99}";

    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);  // 表示遇到未知屬性時,不會報錯
    final Department department = mapper.readValue(json, Department.class);
    System.out.println(department);
    // Department(depName=QA, addr=beijing, superior=null)
}

   

3.五、對象轉json時,生成格式化的json字符串

  在writeValueAsString(Object obj)以前,mapper先調用writerWithDefaultPrettyPrinter()方法便可

@Test
public void test6() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();

    Department department1 = new Department();
    department1.setDepName("QA");
    department1.setAddr("beijing");
    department1.setSuperior("小強");
    final String depJsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(department1);
    System.out.println(depJsonStr);
    /*
    {
        "depName" : "QA",
        "addr" : "beijing",
        "superior" : "小強"
    }
    */
}
相關文章
相關標籤/搜索