一、前言
之前簡單的瞭解了一下JSON的一些類似JSON是個啥,爲什麼要有JSON,JSON與XML的區別,JSON的語法規則等基礎概念(可跳轉學習筆記:https://blog.csdn.net/qq_38586378/article/details/102989550),想着後端尤其在Java Web項目中的話應該是要學會Java與JSON的相互轉換的,恰好之前畢設的時候又遇到過這個技術點,就是Jackson,就簡單的做了個小demo進行記錄。
二、參考鏈接
- https://blog.csdn.net/u011054333/article/details/80504154
- https://www.cnblogs.com/naaoveGIS/p/3893651.html
- https://www.jianshu.com/p/4bd355715419
- https://www.yiibai.com/jackson
三、知識點及技術的簡單介紹
3.1 JSON
JSON,JavaScript Object Notation,一種輕量級數據轉換格式;本身就是一個字符;不受編程語言限制,支持與多種類型數據進行轉換;表示方法是名稱 : 值,其中名稱爲字符串,值可爲整數、浮點數、字符串、布爾值、數組、對象和null,其中數組數據在 [] 中,對象數據在 {} 中;數據間使用 , 隔開;JSON相對於XML,數據結構更簡潔,更適合於面向對象的通過RESTful API通信的應用程序開發。
3.2 Jackson
Jackson是一個簡單的基於Java的應用庫,可輕鬆完成Java對象與JSON、XML的相互轉換;依賴jar包少,性能高;社區活躍,更新快。
一般處理JSON有三種方式:
- 流式API——讀取JSON並將JSON寫入作爲離散事件,主要涉及JsonParser和JsonGenerator方法,前者讀取數據,後者寫入數據。是最有效、最低開銷、最快的讀/寫操作
- 樹模型——準備JSON文件並以樹的形式保存在內存中,主要涉及JsonNode節點,readTree方法讀取樹
- 數據綁定——轉換JSON,主要分爲簡單的數據綁定和全部數據綁定。前者是轉換JSON和Java的Map、List、String、整數、布爾值和null對象;後者是指將JSON轉爲任何的Java對象。使用ObjectMapper的writeValueAsString將Java對象轉JSON,readValue方法將JSON轉爲Java對象
Jackson涉及三個核心模塊:
- jackson-core:定義低級的流式API,包括JSON處理細節
- jackson-annotation:包括Jackson註解
- jackson-databind:實現Java對象與JSON的相互轉換
一般使用方法,以Spring Boot爲例,直接在pom.xml配置文件中加以jackson-databind依賴即可(最好是把Jackson的三個核心模塊都給加上,有一些異常處理可能需要import一下)。
四、實現過程
4.1 Java實體類創建
設計一個Student對象,對象屬性有ID、Name、Sex、Class班級、Address、Parents(Map類型,key爲father/mother,value爲name和telephone),在Student類中加入構造函數和toString方法以及setter、getter方法(雖然好像後期並沒有用到,但是對於private類型的屬性,外界調用只能通過get和set方法/new 構造體實現對象實例化)
4.2 測試
4.2.1 Java對象轉JSON對象
通過new Student實例化Student對象,使用ObjectMapper對象的
writeValueAsString()方法實現將Java對象轉爲JSON並輸入。
輸出結果爲:
4.2.2 JSON對象轉Java對象
在講JSON對象轉爲Java對象的時候需要注意,如果單純使用ObjectMapper的readValue方法,結果會報錯如下
解決方法是在創建好的實體類的構造方法前加@JsonCreator註釋,並在構造方法的參數中添加@JsonProperty註釋
如此即可解決該問題,JSON轉Java對象的方法如下圖
結果如下:
4.2.3 數組轉JSON對象
和Java對象轉JSO類似,直接上圖,將創建好的List對象以JSON格式輸出
4.2.4 JSON對象轉數組
此處需要注意,ObjectMapper的readValue方法中的第二參數應該爲New TypeReference<T>() {},見下圖 注意此處的TypeRerence是引用的
com.fasterxml.jackson.core.type.TypeReference
4.2.3與4.2.4結果圖如下
4.2.5 如果Java對象實例化的時候有空值,JSON直接輸出null(構造函數中去掉stuParents屬性)
4.2.6 如果想輸出忽略掉null值,可在實體類前面加@JsonInclue(JsonInclude.Include.Type)註釋,其中Type有NON_NULL、NON_ABSENT、NON_DEFAULT、NON_EMPTY,其中NON_EMPTY指輸出忽略爲空的字符串。
使用NON_NULL輸出4.2.5結果,可以看到輸出Json已經忽略掉了值爲null的stuParents
再如使用NON_EMPTY,並且恢復輸出stuParents,單純給這個Map對象初始化但是不賦值,結果輸出如下,轉爲JSON忽略爲空的stuParents 需要注意null並不等同於爲空,爲空是指值爲空,null是根本就沒有這個對象(於JSON與Java轉換而言)
五、總結
通過Jackson的數據綁定方式實現Java對象和數組與JSON間的相互轉換,簡單瞭解了Jackson的使用方法,有關JSON和Jackson的學習暫時告一段落,後續有使用到的覺得值得記錄的店會繼續進行更新。
博客中的完整代碼如下,簡單的一個小demo,歡迎指正~
5.1 Student類
package com.practice.json.entity;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import java.util.Map;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Student {
private Integer stuID;
private String stuName;
private String stuSex;
private String stuClass;
private String stuAddr;
/**
* Map key is father/mother, Value is father/mother's info(name,telephone)
*/
@JsonIgnoreProperties(ignoreUnknown = true)
private Map<String,List<String>> stuParents;
@JsonCreator
public Student(@JsonProperty("stuID") Integer stuID, @JsonProperty("stuName") String stuName,
@JsonProperty("stuSex")String stuSex, @JsonProperty("stuClass")String stuClass,
@JsonProperty("stuAddr")String stuAddr,@JsonProperty("stuParents")Map<String,List<String>> stuParents) {
this.stuID = stuID;
this.stuName = stuName;
this.stuSex = stuSex;
this.stuClass = stuClass;
this.stuClass = stuClass;
this.stuAddr = stuAddr;
this.stuParents = stuParents;
}
@Override
public String toString() {
return "Student{" +
"stuID=" + stuID +
", stuName='" + stuName + '\'' +
", stuSex='" + stuSex + '\'' +
", stuClass='" + stuClass + '\'' +
", stuAddr='" + stuAddr + '\'' +
", stuParents=" + stuParents +
'}';
}
public Integer getStuID() {
return stuID;
}
public void setStuID(Integer stuID) {
this.stuID = stuID;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuSex() {
return stuSex;
}
public void setStuSex(String stuSex) {
this.stuSex = stuSex;
}
public String getStuClass() {
return stuClass;
}
public void setStuClass(String stuClass) {
this.stuClass = stuClass;
}
public String getStuAddr() {
return stuAddr;
}
public void setStuAddr(String stuAddr) {
this.stuAddr = stuAddr;
}
public Map<String, List<String>> getStuParents() {
return stuParents;
}
public void setStuParents(Map<String, List<String>> stuParents) {
this.stuParents = stuParents;
}
}
5.2 測試類
package com.practice.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.practice.json.entity.Student;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest
class JsonApplicationTests {
@Test
void contextLoads() throws JsonProcessingException {
List<String> lists = new ArrayList<String>();
lists.add("Wang");
lists.add("1536987452");
Map<String, List<String>> map = new HashMap<String, List<String>>();
map.put("father",lists);
Student student = new Student(101,"ciery","female","1904","xi'an",map);
ObjectMapper mapper = new ObjectMapper();
String jsonStrObject = mapper.writeValueAsString(student);
System.out.println("Java object turn to JSON object: " + jsonStrObject);
Student object = mapper.readValue(jsonStrObject,Student.class);
System.out.println("JSON object turn to Java object: " + object.toString());
String jsonStrList = mapper.writeValueAsString(lists);
System.out.println("List turn to JSON object: " + jsonStrList);
List<String> list = mapper.readValue(jsonStrList,new TypeReference<List<String>>(){});
System.out.println("JSON object turn to List: " + list.get(0) + ", " + list.get(1));
}
}
5.3 Spring Boot配置
直接建立一個Spring Boot項目,在項目創建時未加依賴,後期使用到Jackson的時候直接在pom.xml中添加fasterxml的相關依賴,有關Jackson的依賴可以在該鏈接進行復制:https://mvnrepository.com/artifact/com.fasterxml.jackson.core
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.0</version>
</dependency>