Json是一種輕量級的數據交換格式,采用一種“鍵:值”對的文本格式來存儲和表示數據,在系統交換數據過程中常常被使用,是一種理想的數據交換語言。在使用Java做Web開發時,不可避免的會遇到Json的使用。下面我們就簡單講一下Json的使用以及fastjson.jar包的使用。
一:JSON形式與語法
1.1:JSON對象
我們先來看以下數據:
{
"ID": 1001,
"name": "張三",
"age": 24
}
第一個數據就是一個Json對象,觀察它的數據形式,可以得出以下語法:
1:數據在花括號中
2:數據以"鍵:值"對的形式出現(其中鍵多以字符串形式出現,值可取字符串,數值,甚至其他json對象)
3:每兩個"鍵:值"對以逗號分隔(最后一個"鍵:值"對省略逗號)
遵守上面3點,便可以形成一個json對象。
1.2:JSON對象數組
接下來我們再看第二個數據,觀察它的數據形式,可以得出以下語法:
[
{"ID": 1001, "name": "張三", "age": 24},
{"ID": 1002, "name": "李四", "age": 25},
{"ID": 1003, "name": "王五", "age": 22}
]
1:數據在方括號中(可理解為數組)
2:方括號中每個數據以json對象形式出現
3:每兩個數據以逗號分隔(最后一個無需逗號)
遵守上面3點,便可形成一個json對象數組(及一個數組中,存儲了多個json對象)
理解了上面兩種基本的形式,我們就可以得出其他的數據形式,例如下面這個:
{
"部門名稱":"研發部",
"部門成員":[
{"ID": 1001, "name": "張三", "age": 24},
{"ID": 1002, "name": "李四", "age": 25},
{"ID": 1003, "name": "王五", "age": 22}],
"部門位置":"xx樓21號"
}
這是上面兩個基本形式結合出來的一種變形,通過這種變形,使得數據的封裝具有很大的靈活性,能讓開發者自由的發揮想象力。
1.3:JSON字符串
JSON字符串也是在平時開發中使用較多的,json字符串應滿足以下條件:
1:它必須是一個字符串,由" "或者' '包裹數據,支持字符串的各種操作
2:里面的數據格式應該要滿足其中一個格式,可以是json對象,也可以是json對象數組或者是兩種基本形式的組合變形。
總結:json可以簡單的分為基本形式:json對象,json對象數組。兩種基本格式組合變形出其他的形式,但其本質還是json對象或者json對象數組中的一種。json對象或對象數組可以轉化為json字符串,使用於不同的場合。
注意點:在封裝json數據的時候,很容易出現錯誤,比如粗心的在最后一條數據的末尾加上了逗號等等,這里我提供一個在線驗證工具,方便大家驗證json數據格式的正確性
http://www.bejson.com/
二:fastjson介紹與使用
2.1:fastjson簡介與jar下載
fastjson.jar是阿里爸爸開發的一款專門用於Java開發的包,可以方便的實現json對象與JavaBean對象的轉換,實現JavaBean對象與json字符串的轉換,實現json對象與json字符串的轉換。除了這個fastjson以外,還有Google開發的Gson包,其他形式的如net.sf.json包,都可以實現json的轉換。方法名稱不同而已,最后的實現結果都是一樣的。
將json字符串轉化為json對象
在net.sf.json中是這么做的
JSONObject obj = new JSONObject().fromObject(jsonStr);//將json字符串轉換為json對象
在fastjson中是這么做的
JSONObject obj=JSON.parseObject(jsonStr);//將json字符串轉換為json對象
今天我們主要講fastjson的使用,首先應該在Java工程中導入對應的fastjson.jar包,
fastjson.jar包原始下載地址:https://github.com/alibaba/fastjson
點擊頁面中的download即可下載最新的包
2.2:fastjson源碼分析與使用
在包中,可以發現主要的3個類,JSON,JSONArray,JSONObject
三者之間的關系如下,JSONObject和JSONArray繼承JSON
聯系上面講到的json基礎知識並對應這三個類,可以發現,JSONObject代表json對象,JSONArray代表json對象數組,
JSON代表JSONObject和JSONArray的轉化。
JSONObject類源碼分析與使用
觀察該類的繼承與實現關系,不難發現,JSONObject實現了Map接口,而json對象中的數據都是以"鍵:值"對形式出現,可以猜想, JSONObject底層操作是由Map實現的。再來看類中的主要方法:
類中主要是get()方法。因為JSONObject相當於json對象,所以該類中主要封裝了各種get方法,通過"鍵:值"對中的鍵來獲取其對應的值。且方法的輸入參數幾乎皆為String類型,這是因為json對象中,"鍵:值"對的鍵都是String類型的。來看一下平時用到較多的 getString(String key)方法,該方法輸入參數為String key(鍵),輸出為String ,用於獲取json對象中的字符串型數據。例如通過該方法獲取 "name":"bob"鍵值對中name這個鍵所對應的值bob。
看其源碼,可以發現,內部主要是由get(key)方法實現,找到這個方法如下:
發現內部主要由Map接口中的get()方法實現。
再去看JSONObject中另一個常用的方法getInteger(String key),該方法獲取json對象中的整型數據,例如獲取"age:20"鍵值對中age對應的整型數值20.
對比getString(String key)方法,兩者極為相似,都是通過Map接口的get()方法實現。
再看幾個其他的方法,也是由Map接口中的相應方法實現的,這里不再贅述。
總結:JSONObject對應json對象,通過各種形式的get()方法可以獲取json對象中的數據,也可利用諸如size(),isEmpty()等方法獲取"鍵:值"對的個數和判斷是否為空。其本質是通過實現Map接口並調用接口中的方法完成的。
JSONArray類源碼分析與使用
觀察JSONArray的繼承與實現,並結合上面對JSONObject的分析,不難發現,其內部是有List接口中的方法來完成操作的。
同樣觀察JSONArray類中的方法,由於方法較多,下面分為兩部分
首先來明確一點,因為JSONArray代表json對象數組,json數組對象中存儲的是一個個json對象,所以類中的方法主要用於直接操作json對象。比如這其中的add(),remove(),containsAll()方法,對應於json對象的添加,刪除與判斷。
其內部主要有List接口中的對應方法來實現。
跟JSONObject一樣,JSONArray里面也有一些get()方法,不過都不常用,最有用的應該是getJSONObject(int index)方法,該方法用於獲取json對象數組中指定位置的JSONObject對象,配合size()方法,可用於遍歷json對象數組中的各個對象。
通過以上兩個方法,在配合for循環,即可實現json對象數組的遍歷,當然JSONArray中也實現了迭代器方法來遍歷,這和List的遍歷極為相似。
通過遍歷得到JSONObject對象,然后再利用JSONObject類中的get()方法,即可實現最終json數據的獲取!!!
好了,接下來我們看最后一個,也是最重要的一個類JSON類。之所以把這個放在最后,是因為這個類主要是實現轉化用的,最后的數據獲取,還是要通過上面的JSONObject和JSONArray來實現。
JSON類源碼分析與使用
先來看一下這個類中的主要方法,方法比較多,也分為兩部分:
仔細觀察這些方法,主要是實現json對象,json對象數組,javabean對象,json字符串之間的相互轉化。
JSON類之toJSONString()方法,實現json對象轉化為json字符串和javabean對象轉化為json 字符串
該方法經過多次重載,但最終都是實現json對象轉化為json字符串和javabean對象轉化為json 字符串。其中,有關鍵字transient修飾的toJSONString()用於json對象序列化過程中,希望某個"鍵:值"對數據不變的應用中。
JSON類之parseObject()方法,實現json字符串轉換為json對象或javabean對象
該方法返回JSONObject對象,用於實現json字符串向json對象的轉化,其內部調用了parse()方法,調用底層的DefaultJSONParser解析類進行轉化,在轉化失敗時,拋出can not cast to JSONObject異常。
該方法不僅能實現json字符串向json對象的轉化,經過重載之后,還能實現json字符串向javabean對象的轉化
json字符串與javaBean之間的轉換可以使用 TypeReference<T> 這個類,也可以使用Class這個類。
Student stu1=JSON.parseObject(jsonstr,new TypeReference<Student>(){});
Student stu1=JSON.parseObject(jsonstr,Student.class);
我推薦使用第二種Class類反射來實現,比較簡單。
JSON類之JSONArray()方法,實現json字符串轉化為json對象數組或List<T>
與parseObject()方法類似,parseArray()將json字符串轉化為json對象數組或轉化成包含泛型的List
該方法用的比較少,主要用於將javabean對象轉化為json對象,內部通過Map,LinkedHashMap,HashMap等集合接口實現。
JSON類之toJavaObject()方法,實現json對象轉化為javabean對象
該方法也經過重載,通過TypeReference類和Class類反射來實現,主要講json對象轉化為javabean對象,用的也比較少。
至此,JSON類中的方法也講解的差不多了,下面給出Java實例來實現以上的各種轉換。
測試類:
package jsonTest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
public class MyJson {
public static void main(String[] args) {
List<Student> list=new ArrayList<>();
Student student=new Student("bob",24);
Student student12=new Student("lily", 23);
list.add(student);
list.add(student12);
System.out.println("*******javaBean to jsonString*******");
String str1=JSON.toJSONString(student);
System.out.println(str1);
System.out.println(JSON.toJSONString(list));
System.out.println();
System.out.println("******jsonString to javaBean*******");
//Student stu1=JSON.parseObject(str1,new TypeReference<Student>(){});
Student stu1=JSON.parseObject(str1,Student.class);
System.out.println(stu1);
System.out.println();
System.out.println("******javaBean to jsonObject******");
JSONObject jsonObject1=(JSONObject)JSON.toJSON(student);
System.out.println(jsonObject1.getString("name"));
System.out.println();
System.out.println("******jsonObject to javaBean******");
Student student2=JSON.toJavaObject(jsonObject1, Student.class);
System.out.println(student2);
System.out.println();
System.out.println("*******javaBean to jsonArray******");
List<Student> stulist=new ArrayList<>();
for(int i=0;i<5;i++){
stulist.add(new Student("student"+i, i));
}
JSONArray jsonArrays=(JSONArray)JSON.toJSON(stulist);
for(int i=0;i<jsonArrays.size();i++){
System.out.println(jsonArrays.getJSONObject(i));
}
System.out.println();
System.out.println("*****jsonArry to javalist******");
List<Student> myList=new ArrayList<>();
for(int i=0;i<jsonArrays.size();i++){
Student student3=JSON.toJavaObject(jsonArrays.getJSONObject(i), Student.class);
myList.add(student3);
}
for(Student stu:myList){
System.out.println(stu);
}
System.out.println();
System.out.println("*****jsonObject to jsonString*****");
String str4=JSON.toJSONString(jsonObject1);
System.out.println(str4);
System.out.println();
System.out.println("*******jsonString to jsonObject*****");
JSONObject jso1=JSON.parseObject(str1);
System.out.println(jso1.getString("name"));
System.out.println();
System.out.println("*****jsonString to jsonArray*****");
JSONArray jArray=JSON.parseArray(JSON.toJSONString(stulist));
for(int i=0;i<jArray.size();i++){
System.out.println(jArray.getJSONObject(i));
}
System.out.println();
}
}
測試類對應的javabean類:
package jsonTest;
public class Student {
private String name;
private int age;
public Student() {
// TODO Auto-generated constructor stub
}
public Student(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "student [name="+name+" , "+"age="+age+"]";
}
}