JSON(JavaScript Object Notation)
是一種與開發語言無關的、輕量級的 數據格式;重點記住,它是一種數據格式 ;javascript
很是易於人的閱讀和編寫,同時也很容易被程序解析 ;java
使用花括號 {}
括起來的鍵值對結構,其中 key
必須是 String
類型,value
爲 任何
基本類型 或 數據結構 ;web
其中鍵值對內部使用冒號 :
鏈接, 鍵值對之間使用逗號 ,
鏈接 ;json
使用中括號 []
括起來,元素之間使用逗號 ,
分隔 ;數組
元素也是能夠爲 任何
類型 ;數據結構
JSON 的基本類型有 5
種:ide
string
表明字符串 ,字符串須要用雙引號 " "
括起來 ;number
數值類型,JSON
中只有一個 number
類型,是沒有 int float double
這些類型的 ;true/false
布爾類型null
JSON
中也定義了一個表明 空
的關鍵字 ;能夠看見 JSON
好多的格式,都不支持,好比 日期
類型,這也是 JSON
的一個缺點,下面介紹的 GSON
彌補了這一缺點 ;svg
使用 JSONObject
對象構建 JSON
數據工具
@Test public void object2Json(){ // 定義一個 null 對象 ; Object NULL = null ; // 利用 jsonObject 對象,構建 JSON JSONObject jsonObject = new JSONObject() ; jsonObject.put("name","yaz") ; jsonObject.put("sex","男") ; // 日期類型,用字符串,JSON 裏面沒有日期類型 jsonObject.put("birthday","1997-01-22") ; // 插入數字的時候,java的數值類型,最後都會被轉爲 JSON 的number 類型 jsonObject.put("salary",5000.00) ; jsonObject.put("age",22) ; jsonObject.put("hasHouse",false) ; // 直接傳入 null ,編譯不經過,由於 put 重載了 Collection 和 map 集合 ; // 直接傳入 null ,就不知道具體調用哪個了 // 定義一個 null 對象,繞過編譯 ; // 值爲 null 的屬性,不會被傳入到 JSON 中 ; jsonObject.put("hasDream",NULL) ; jsonObject.put("habit",new String[]{"LOL","打乒乓球","java-IT"}) ; System.out.println(jsonObject.toString()); }
生成的 JSON
字符串 :ui
{ "birthday": "1997-01-22", "sex": "男", "habit": [ "LOL", "打乒乓球", "java-IT" ], "hasHouse": false, "age": 22, "name": "yaz", "salary": 5000 }
使用 Map
對象構建 JSON
數據
@Test public void map2Json(){ Map<String,Object> map = new HashMap<>(); map.put("name","yaz") ; map.put("age",22) ; map.put("birthday","97-01-22") ; map.put("salary",5000.1) ; map.put("habit",new String[]{"LOL","Music","sleep"}) ; map.put("hasHouse",false) ; map.put("car",null) ; // 仍是須要 JSONObject ,將 map 傳入 JSONObject jsonObject = new JSONObject(map) ; System.out.println(jsonObject); }
生成的 JSON
字符串 :
{ "birthday": "97-01-22", "habit": [ "LOL", "Music", "sleep" ], "hasHouse": false, "name": "yaz", "age": 22, "salary": 5000.1 }
使用 Javabean
對象構建 JSON
數據 (推薦使用)
@Test public void Javabean2Json(){ Customer customer = new Customer() ; customer.setAge(20); customer.setBirtyday("97-02-28"); customer.setCarName(null); customer.setHabit(new String[]{"lol","java-IT"}); customer.setSalary(5000.1); customer.setHasHouse(false); JSONObject jsonObject = new JSONObject(customer); System.out.println(jsonObject); }
生成的 JSON
字符串 :
{ "birtyday": "97-02-28", "habit": [ "lol", "java-IT" ], "hasHouse": false, "age": 20, "salary": 5000.1 }
總結:
JSON
串,都須要 JSONObject
對象 ,能夠往裏面一個一個屬性的 put
,也能夠直接傳給它一個 map
,或者一個 Javabean
對象;null
的屬性,是不會爲添加到 JSON
串中的 ;從文件中讀取 JSON
解析數組
這裏有個缺點:JSON
的工具類不能直接解析數組,須要使用 JSONArray
類輔助下 ;
判斷 null
使用 jsonObject.isNull("鍵")
判斷對應的屬性,是否存在 ; ;
@Test public void json2Object() throws IOException { // 獲取 json 串所在的文件 File file = new File(this.getClass().getClassLoader().getResource("jsonString.txt").getFile()); // 使用 Apache 的 fileUtils工具,讀取文本文件內容,轉成字符串 String json = FileUtils.readFileToString(file, "UTF-8"); // 仍是使用 JSONObject 對象 JSONObject jsonObject = new JSONObject(json); // 讀取 JSON 串的內容 // 判斷 是否有 name 屬性,若是沒有,則不讀取; if (!jsonObject.isNull("name")) { System.out.println("name" + jsonObject.getString("name")); } System.out.println("age" + jsonObject.getInt("age")); System.out.println("salary" + jsonObject.getInt("salary")); // 可是讀取數組,須要使用另一個對象 JSONArray jsonArray = jsonObject.getJSONArray("habit"); for (int i = 0; i < jsonArray.length(); i++) { // 須要強轉下 String habit = (String) jsonArray.get(i); System.out.println("habit " + i + ":" + habit); } }
這裏有個坑:地址的寫法,注意了,以前的寫法,一直很差使,最後,直接創建一個資源文件,扔下面,而後訪問到了
總結:解析 JSON
串的時候,須要咱們本身一個一個的去獲取屬性,對於數組屬性,還須要強轉,由於它不知道里面的具體類型 ;
Google
的一個開源項目,對 JSON
進行了加強,好比支持了日期類型;
@Test public void object2Gson() throws ParseException { CustomerWithDate customerWithDate = new CustomerWithDate(); customerWithDate.setAge(22); customerWithDate.setName("yaz"); customerWithDate.setBirtyday(new SimpleDateFormat("yyyy-mm-dd").parse("1997-1-22")); customerWithDate.setHabit(new String[]{"lol", "java"}); // 這個不會獲得構建 customerWithDate.setPassword("sasas"); // 美化輸出樣式,使用 GsonBuilder GsonBuilder gsonBuilder = new GsonBuilder(); // 進行個性化定製輸出,也就是在構建的時候,對字段進行一些設定 gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() { @Override public String translateName(Field field) { if ("name".equals(field.getName())){ return "YAZZZZ" ; } return field.getName(); } }) ; gsonBuilder.setPrettyPrinting(); Gson gson = gsonBuilder.create(); System.out.println(gson.toJson(customerWithDate)); }
使用 Javabean
或者 map
對象 均可以,toJson
操做,參數是一個 object
類型 ;
能夠解析成本身的對象,而不是像 JSON
那樣,解析成 JSONObject
對象 ;
@Test public void gson2Object() throws IOException { // 獲取 json 串所在的文件 // 地址的寫法,注意了,以前的寫法,一直很差使,直接創建一個資源文件,扔下面,而後訪問到了 File file = new File(this.getClass().getClassLoader().getResource("jsonString.txt").getFile()); // 使用 Apache 的 fileUtils工具,讀取文本文件內容,轉成字符串 String json = FileUtils.readFileToString(file, "UTF-8"); // 建立一個 支持解析日期 的 gson Gson gson = new GsonBuilder().setDateFormat("yyyy-mm-dd").create() ; CustomerWithDate customerWithDate = gson.fromJson(json,CustomerWithDate.class); System.out.println(customerWithDate); }
支持改變生成 JSON
的屬性名(別名)
/** * 設置別名,使用註解 */ @SerializedName("NAME") private String name;
美化輸出
// 美化輸出樣式,使用 GsonBuilder GsonBuilder gsonBuilder = new GsonBuilder() ; // 設置成漂亮的輸出 gsonBuilder.setPrettyPrinting();
在解析的過程當中,進行個性化定製
// 進行個性化定製輸出,也就是在構建的時候,對字段進行一些設定 gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() { @Override public String translateName(Field field) { if ("name".equals(field.getName())){ return "YAZZZZ" ; } return field.getName(); } }) ;
忽略掉某些 Javabean
的屬性
// 使用關鍵字 transient 在構建 JSON 的時候,會忽略掉該屬性 private transient String password;
支持解析日期
設定日期解析格式 ;
// 建立一個 支持解析日期 的 gson Gson gson = new GsonBuilder().setDateFormat("yyyy-mm-dd").create() ;
支持 JSON
Array
數組到 java
集合類的無縫轉換
說的是,對於 JSON
的 Array
數組,咱們在 java 裏面是能夠直接用 集合
接收的, GSON
會自動的轉換 ;