?原文作者:江戶小寶 ? ? ?原文鏈接:https://zhuanlan.zhihu.com/p/62763428
?
在進(jìn)行數(shù)據(jù)處理或前后端交互的時候,會不可避免的碰到j(luò)son格式的數(shù)據(jù)。Json是一種輕量級的數(shù)據(jù)交換格式,采用一種“鍵:值”對的文本格式來存儲和表示數(shù)據(jù),是一種理想的數(shù)據(jù)交換語言。本文對son的使用以及fastjson包的使用進(jìn)行闡述,通過本文的學(xué)習(xí),可以解決部分常見的JSON數(shù)據(jù)問題。
一、JSON形式與語法
1.1 JSON對象
{"ID": 1001,"name": "張三","age": 24}
這個數(shù)據(jù)就是一個Json對象,Json對象的特點如下:
- 數(shù)據(jù)在花括號中
- 數(shù)據(jù)以"鍵:值"對的形式出現(xiàn)(其中鍵多以字符串形式出現(xiàn),值可取字符串,數(shù)值,甚至其他json對象)
- 每兩個"鍵:值"對以逗號分隔(最后一個"鍵:值"對省略逗號)
1.2 JSON對象數(shù)組
代碼解讀
復(fù)制代碼[
{"ID": 1001, "name": "張三", "age": 24},
{"ID": 1002, "name": "李四", "age": 25},
{"ID": 1003, "name": "王五", "age": 22}
]
這個數(shù)據(jù)就是一個Json對象數(shù)組,Json對象數(shù)組的特點如下:
- 數(shù)據(jù)在方括號中(可理解為數(shù)組)方括號中每個數(shù)據(jù)以json對象形式出現(xiàn)每兩個數(shù)據(jù)以逗號分隔(最后一個無需逗號)
上面兩個是Json的基本形式,結(jié)合在一起就可以得出其他的數(shù)據(jù)形式,例如這個:
代碼解讀
復(fù)制代碼{
"部門名稱":"研發(fā)部",
"部門成員":[
{"ID": 1001, "name": "張三", "age": 24},
{"ID": 1002, "name": "李四", "age": 25},
{"ID": 1003, "name": "王五", "age": 22}],
"部門位置":"xx樓21號"
}
通過這種變形,使得數(shù)據(jù)的封裝具有很大的靈活性。
1.3:JSON字符串
Json字符串應(yīng)滿足以下條件:
- 它必須是一個字符串,支持字符串的各種操作里面的數(shù)據(jù)格式應(yīng)該要滿足其中一個格式,可以是json對象,也可以是json對象數(shù)組或者是兩種基本形式的組合變形。
總結(jié):json可以簡單的分為基本形式:json對象,json對象數(shù)組。兩種基本格式組合變形出其他的形式,但其本質(zhì)還是json對象或者json對象數(shù)組中的一種。json對象或?qū)ο髷?shù)組可以轉(zhuǎn)化為json字符串,使用于不同的場合。
二、 Fastjson介紹
2.1 Fastjson簡介
fastjson是阿里巴巴開發(fā)的一款專門用于Java開發(fā)的包,可以方便的實現(xiàn)json對象與JavaBean對象的轉(zhuǎn)換,實現(xiàn)JavaBean對象與json字符串的轉(zhuǎn)換,實現(xiàn)json對象與json字符串的轉(zhuǎn)換。除了這個fastjson以外,還有Google開發(fā)的Gson包,其他形式的如net.sf.json包,都可以實現(xiàn)json的轉(zhuǎn)換。
2.2 Fastjson使用
在fastjson包中主要有3個類,JSON,JSONArray,JSONObject
三者之間的關(guān)系如下,JSONObject和JSONArray繼承JSON
![](/files/attmgn/2025/1/liguoquan20250114162846533_0.jpg)
聯(lián)系上面講到的json基礎(chǔ)知識并對應(yīng)這三個類,可以發(fā)現(xiàn),JSONObject代表json對象,JSONArray代表json對象數(shù)組,JSON代表JSONObject和JSONArray的轉(zhuǎn)化。
2.2.1 JSONObject類使用
JSONObject實現(xiàn)了Map接口,而json對象中的數(shù)據(jù)都是以"鍵:值"對形式出現(xiàn), JSONObject底層操作是由Map實現(xiàn)的。類中主要是get()方法。JSONObject相當(dāng)于json對象,該類中主要封裝了各種get方法,通過"鍵:值"對中的鍵來獲取其對應(yīng)的值。
2.2.2 JSONArray類使用
JSONArray的內(nèi)部是通過List接口中的方法來完成操作的。JSONArray代表json對象數(shù)組,json數(shù)組對象中存儲的是一個個json對象,所以類中的方法主要用于直接操作json對象。比如其中的add(),remove(),containsAll()方法,對應(yīng)于json對象的添加,刪除與判斷。 其內(nèi)部主要由List接口中的對應(yīng)方法來實現(xiàn)。
跟JSONObject一樣,JSONArray里面也有一些get()方法,不過不常用,最有用的應(yīng)該是getJSONObject(int index)方法,該方法用于獲取json對象數(shù)組中指定位置的JSONObject對象,配合size()方法,可用于遍歷json對象數(shù)組中的各個對象。 通過以上兩個方法,在配合for循環(huán),即可實現(xiàn)json對象數(shù)組的遍歷。此外JSONArray中也實現(xiàn)了迭代器方法來遍歷。 通過遍歷得到JSONObject對象,然后再利用JSONObject類中的get()方法,即可實現(xiàn)最終json數(shù)據(jù)的獲取。
2.2.3 JSON類使用
JSON類主要是實現(xiàn)轉(zhuǎn)化用的,最后的數(shù)據(jù)獲取,還是要通過JSONObject和JSONArray來實現(xiàn)。類中的主要是實現(xiàn)json對象,json對象數(shù)組,javabean對象,json字符串之間的相互轉(zhuǎn)化。
總結(jié)一下fastjson中三個類的用途和方法:
- JSONObject:解析Json對象,獲取對象中的值,通常是使用類中的get()方法
- JSONArray:JSON對象數(shù)組,通常是通過迭代器取得其中的JSONObject,再利用JSONObeject的get()方法進(jìn)行取值。
- JSON:主要是實現(xiàn)json對象,json對象數(shù)組,javabean對象,json字符串之間的相互轉(zhuǎn)化。 轉(zhuǎn)換之后取值還是按各自的方法進(jìn)行。
三 、JSON案例
3.1 json字符串—》JSONObject
用JSON.parseObject()方法即可將JSon字符串轉(zhuǎn)化為JSON對象,利用JSONObject中的get()方法來獲取JSONObject中的相對應(yīng)的鍵對應(yīng)的值
代碼解讀
復(fù)制代碼import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.jiyong.config.Student;
import com.jiyong.config.Teacher;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Fastjson用法
*/
public class FastJsonOper {
//json字符串-簡單對象型,加\轉(zhuǎn)義
private static final String JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
//json字符串-數(shù)組類型
private static final String JSON_ARRAY_STR = " [{\"studentName\":\"lily\",\"studentAge\":12}," +
"{\"studentName\":\"lucy\",\"studentAge\":15}]";
//復(fù)雜格式j(luò)son字符串
private static final String COMPLEX_JSON_STR = "{\"teacherName\":\"crystall\"," +
"\"teacherAge\":27,\"course\":{\"courseName\":\"english\",\"code\":1270},\"students\":[{\"studentName\":\"lily\",\"studentAge\":12},{\"studentName\":\"lucy\",\"studentAge\":15}]}";
// json字符串與JSONObject之間的轉(zhuǎn)換
@Test
public void JsonStrToJSONObject(){
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
System.out.println("StudentName: " + jsonObject.getString("studentName") + "," + "StudentAge: " + jsonObject.getInteger("studentAge"));
}
}
3.2 JSONObject—》json字符串
用JSON.toJSONString()方法即可將JSON對象轉(zhuǎn)化為JSON字符串
代碼解讀
復(fù)制代碼 /**
* 將JSONObject轉(zhuǎn)換為JSON字符串,用JSON.toJSONString()方法即可將JSON字符串轉(zhuǎn)化為JSON對象
*/
@Test
public void JSONObjectToJSONString(){
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
String s = JSON.toJSONString(jsonObject);
System.out.println(s);
}
3.3 JSON字符串?dāng)?shù)組—》JSONArray
將JSON字符串?dāng)?shù)組轉(zhuǎn)化為JSONArray,通過JSON的parseArray()方法。JSONArray本質(zhì)上還是一個數(shù)組,對其進(jìn)行遍歷取得其中的JSONObject,然后再利用JSONObject的get()方法取得其中的值。有兩種方式進(jìn)行遍歷
- 方式一:通過jsonArray.size()獲取JSONArray中元素的個數(shù),再通過getJSONObject(index)獲取相應(yīng)位置的JSONObject,循環(huán)變量取得JSONArray中的JSONObject,再利用JSONObject的get()進(jìn)行取值。
- 方式二:通過jsonArray.iterator()獲取迭代器
代碼解讀
復(fù)制代碼/**
* 將JSON字符串?dāng)?shù)組轉(zhuǎn)化為JSONArray,通過JSON的parseArray()方法
*/
@Test
public void JSONArrayToJSONStr(){
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
/**
* JSONArray本質(zhì)上還是一個數(shù)組,對其進(jìn)行遍歷取得其中的JSONObject,然后再利用JSONObject的get()方法取得其中的值
* 方式一是通過jsonArray.size()獲取JSONArray中元素的個數(shù),
* 再通過getJSONObject(index)獲取相應(yīng)位置的JSONObject,在利用JSONObject的get()進(jìn)行取值
* 方式二是通過jsonArray.iterator()獲取迭代器
*
*/
// 遍歷方式一
// int size = jsonArray.size();
// for(int i = 0;i < size;i++){
// JSONObject jsonObject = jsonArray.getJSONObject(i);
// System.out.println("studentName: " + jsonObject.getString("studentName") + ",StudentAge: " + jsonObject.getInteger("studentAge"));
// }
// 遍歷方式二
Iterator<Object> iterator = jsonArray.iterator();
while (iterator.hasNext()){
JSONObject jsonObject = (JSONObject) iterator.next();
System.out.println("studentName: " + jsonObject.getString("studentName") + ",StudentAge: " + jsonObject.getInteger("studentAge"));
}
}
3.4 JSONArray—》json字符串
用JSON.toJSONString()方法即可將JSONArray轉(zhuǎn)化為JSON字符串
代碼解讀
復(fù)制代碼/**
* JSONArray到j(luò)son字符串-數(shù)組類型的轉(zhuǎn)換
*/
@Test
public void JSONArrayToJSONString(){
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
String s = JSON.toJSONString(jsonArray);
System.out.println(s);
}
3.5 復(fù)雜JSON格式字符串—》JSONObject
將復(fù)雜JSON格式字符串轉(zhuǎn)換為JSONObject,也是通過JSON.parseObject()
代碼解讀
復(fù)制代碼 /**
* 將復(fù)雜JSON格式字符串轉(zhuǎn)換為JSONObject,也是通過JSON.parseObject(),可以取其中的部分
*/
@Test
public void JSONStringTOJSONObject(){
JSONObject jsonObject = JSON.parseObject(COMPLEX_JSON_STR);
// 獲取簡單對象
String teacherName = jsonObject.getString("teacherName");
Integer teacherAge = jsonObject.getInteger("teacherAge");
System.out.println("teacherName: " + teacherName + ",teacherAge " + teacherAge);
// 獲取JSONObject對象
JSONObject course = jsonObject.getJSONObject("course");
// 獲取JSONObject中的數(shù)據(jù)
String courseName = course.getString("courseName");
Integer code = course.getInteger("code");
System.out.println("courseName: " + courseName + " code: " + code);
// 獲取JSONArray對象
JSONArray students = jsonObject.getJSONArray("students");
// 獲取JSONArray的中的數(shù)據(jù)
Iterator<Object> iterator = students.iterator();
while (iterator.hasNext()){
JSONObject jsonObject1 = (JSONObject) iterator.next();
System.out.println("studentName: " + jsonObject1.getString("studentName") + ",StudentAge: "
+ jsonObject1.getInteger("studentAge"));
}
}
3.6 復(fù)雜JSONObject—》json字符串
用JSON.toJSONString()方法即可將復(fù)雜JSONObject轉(zhuǎn)化為JSON字符串
代碼解讀
復(fù)制代碼/**
* 復(fù)雜JSONObject到j(luò)son字符串的轉(zhuǎn)換
*/
@Test
public void JSONObjectTOJSON(){
JSONObject jsonObject = JSON.parseObject(COMPLEX_JSON_STR);
String s = JSON.toJSONString(jsonObject);
System.out.println(s);
}
3.7 json字符串—》JavaBean
定義JavaBean類
代碼解讀
復(fù)制代碼package com.fastjson;
public class Student {
private String studentName;
private int studentAge;
public Student() {
}
public Student(String studentName, int studentAge) {
this.studentName = studentName;
this.studentAge = studentAge;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentAge() {
return studentAge;
}
public void setStudentAge(int studentAge) {
this.studentAge = studentAge;
}
@Override
public String toString() {
return "Student{" +
"studentName='" + studentName + '\'' +
", studentAge=" + studentAge +
'}';
}
}
package com.jiyong.config;
/**
* 對于復(fù)雜嵌套的JSON格式,利用JavaBean進(jìn)行轉(zhuǎn)換的時候要注意
* 1、有幾個JSONObject就定義幾個JavaBean
* 2、內(nèi)層的JSONObject對應(yīng)的JavaBean作為外層JSONObject對應(yīng)的JavaBean的一個屬性
* 3、解析方法有兩種
* 第一種方式,使用TypeReference<T>類
* Teacher teacher = JSONObject.parseObject(COMPLEX_JSON_STR, new TypeReference<Teacher>() {})
* 第二種方式,使用Gson思想
* Teacher teacher = JSONObject.parseObject(COMPLEX_JSON_STR, Teacher.class);
*/
import java.util.List;
public class Teacher {
private String teacherName;
private int teacherAge;
private Course course;
private List<Student> students;
public Teacher() {
}
public Teacher(String teacherName, int teacherAge, Course course, List<Student> students) {
this.teacherName = teacherName;
this.teacherAge = teacherAge;
this.course = course;
this.students = students;
}
public String getTeacherName() {
return teacherName;
}
public void setTeacherName(String teacherName) {
this.teacherName = teacherName;
}
public int getTeacherAge() {
return teacherAge;
}
public void setTeacherAge(int teacherAge) {
this.teacherAge = teacherAge;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Teacher{" +
"teacherName='" + teacherName + '\'' +
", teacherAge=" + teacherAge +
", course=" + course +
", students=" + students +
'}';
}
}
package com.jiyong.config;
public class Course {
private String courseName;
private int code;
public Course() {
}
public Course(String courseName, int code) {
this.courseName = courseName;
this.code = code;
}
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
@Override
public String toString() {
return "Course{" +
"courseName='" + courseName + '\'' +
", code=" + code +
'}';
}
}
Jason字符串轉(zhuǎn)換為JavaBean有三種方式,推薦通過反射的方式。
代碼解讀
復(fù)制代碼 /**
* json字符串-簡單對象到JavaBean之間的轉(zhuǎn)換
* 1、定義JavaBean對象
* 2、Jason字符串轉(zhuǎn)換為JavaBean有三種方式,推薦通過反射的方式
*/
@Test
public void JSONStringToJavaBeanObj(){
// 第一種方式
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
String studentName = jsonObject.getString("studentName");
Integer studentAge = jsonObject.getInteger("studentAge");
Student student = new Student(studentName, studentAge);
//第二種方式,使用TypeReference<T>類,由于其構(gòu)造方法使用protected進(jìn)行修飾,故創(chuàng)建其子類
Student student1 = JSON.parseObject(JSON_OBJ_STR, new TypeReference<Student>() {});
// 第三種方式,通過反射,建議這種方式
Student student2 = JSON.parseObject(JSON_OBJ_STR, Student.class);
}
3.8 JavaBean —》json字符串
也是通過JSON的toJSONString,不管是JSONObject、JSONArray還是JavaBean轉(zhuǎn)為為JSON字符串都是通過JSON的toJSONString方法。
代碼解讀
復(fù)制代碼 /**
* JavaBean轉(zhuǎn)換為Json字符串,也是通過JSON的toJSONString,不管是JSONObject、JSONArray還是JavaBean轉(zhuǎn)為為JSON字符串都是通過JSON的toJSONString方法
*/
@Test
public void JavaBeanToJsonString(){
Student lily = new Student("lily", 12);
String s = JSON.toJSONString(lily);
System.out.println(s);
}
3.8 json字符串?dāng)?shù)組—》JavaBean-List
代碼解讀
復(fù)制代碼 /**
* json字符串-數(shù)組類型到JavaBean_List的轉(zhuǎn)換
*/
@Test
public void JSONStrToJavaBeanList(){
// 方式一:
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
//遍歷JSONArray
List<Student> students = new ArrayList<Student>();
Iterator<Object> iterator = jsonArray.iterator();
while (iterator.hasNext()){
JSONObject next = (JSONObject) iterator.next();
String studentName = next.getString("studentName");
Integer studentAge = next.getInteger("studentAge");
Student student = new Student(studentName, studentAge);
students.add(student);
}
// 方式二,使用TypeReference<T>類,由于其構(gòu)造方法使用protected進(jìn)行修飾,故創(chuàng)建其子類
List<Student> studentList = JSON.parseObject(JSON_ARRAY_STR,new TypeReference<ArrayList<Student>>() {});
// 方式三,使用反射
List<Student> students1 = JSON.parseArray(JSON_ARRAY_STR, Student.class);
System.out.println(students1);
}
3.10 JavaBean-List —》json字符串?dāng)?shù)組
代碼解讀
復(fù)制代碼/**
* JavaBean_List到j(luò)son字符串-數(shù)組類型的轉(zhuǎn)換,直接調(diào)用JSON.toJSONString()方法即可
*/
@Test
public void JavaBeanListToJSONStr(){
Student student = new Student("lily", 12);
Student student1 = new Student("lucy", 13);
List<Student> students = new ArrayList<Student>();
students.add(student);
students.add(student1);
String s = JSON.toJSONString(student);
System.out.println(s);
}
3.11 復(fù)雜嵌套json格式字符串—》JavaBean_obj
對于復(fù)雜嵌套的JSON格式,利用JavaBean進(jìn)行轉(zhuǎn)換的時候要注意:
- 有幾個JSONObject就定義幾個JavaBean內(nèi)層的JSONObject
- 對應(yīng)的JavaBean作為外層JSONObject對應(yīng)的JavaBean的一個屬性
代碼解讀
復(fù)制代碼/**
* 復(fù)雜json格式字符串到JavaBean_obj的轉(zhuǎn)換
*/
@Test
public void ComplexJsonStrToJavaBean(){
//第一種方式,使用TypeReference<T>類,由于其構(gòu)造方法使用protected進(jìn)行修飾,故創(chuàng)建其子類
Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, new TypeReference<Teacher>() {});
// 第二種方式,使用反射
Teacher teacher1 = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);
}
3.12 JavaBean_obj —》復(fù)雜json格式字符串
代碼解讀
復(fù)制代碼/**
* 復(fù)雜JavaBean_obj到j(luò)son格式字符串的轉(zhuǎn)換
*/
@Test
public void JavaBeanToComplexJSONStr(){
Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);
String s = JSON.toJSONString(teacher);
System.out.println(s);
}