JSON、GSON


什麼是JSON

JSON(JavaScript Object Notation) 是一種與開發語言無關的、輕量級的 數據格式;重點記住,它是一種數據格式 ;javascript


特色

很是易於人的閱讀和編寫,同時也很容易被程序解析 ;java


JSON的數據結構 – Object

使用花括號 {} 括起來的鍵值對結構,其中 key 必須是 String 類型,value任何 基本類型數據結構web

其中鍵值對內部使用冒號 : 鏈接, 鍵值對之間使用逗號 , 鏈接 ;json


JSON的數據結構 – Array

使用中括號 [] 括起來,元素之間使用逗號 , 分隔 ;數組

元素也是能夠爲 任何 類型 ;數據結構


JSON的數據結構 – 基本類型

JSON 的基本類型有 5 種:ide

  • string 表明字符串 ,字符串須要用雙引號 " " 括起來 ;
  • number 數值類型,JSON 中只有一個 number 類型,是沒有 int float double 這些類型的 ;
  • true/false 布爾類型
  • null JSON 中也定義了一個表明 的關鍵字 ;

能夠看見 JSON 好多的格式,都不支持,好比 日期 類型,這也是 JSON 的一個缺點,下面介紹的 GSON 彌補了這一缺點 ;svg


構建 JSON 數據

  1. 使用 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
    }
  2. 使用 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
    }
  3. 使用 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
    }

總結:

  1. 生成 JSON 串,都須要 JSONObject 對象 ,能夠往裏面一個一個屬性的 put ,也能夠直接傳給它一個 map ,或者一個 Javabean 對象;
  2. 屬性爲 null 的屬性,是不會爲添加到 JSON 串中的 ;

解析 JSON 數據

  1. 從文件中讀取 JSON

  2. 解析數組

    這裏有個缺點:JSON 的工具類不能直接解析數組,須要使用 JSONArray 類輔助下 ;

  3. 判斷 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 串的時候,須要咱們本身一個一個的去獲取屬性,對於數組屬性,還須要強轉,由於它不知道里面的具體類型 ;


GSON

Google 的一個開源項目,對 JSON 進行了加強,好比支持了日期類型;


構建 GSON

@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 類型 ;


解析 GSON

能夠解析成本身的對象,而不是像 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 的強大之處

  1. 支持改變生成 JSON 的屬性名(別名)

    /** * 設置別名,使用註解 */
        @SerializedName("NAME")
        private String name;
  2. 美化輸出

    // 美化輸出樣式,使用 GsonBuilder
            GsonBuilder gsonBuilder = new GsonBuilder() ;
            // 設置成漂亮的輸出
            gsonBuilder.setPrettyPrinting();
  3. 在解析的過程當中,進行個性化定製

    // 進行個性化定製輸出,也就是在構建的時候,對字段進行一些設定
            gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() {
                @Override
                public String translateName(Field field) {
                    if ("name".equals(field.getName())){
                        return "YAZZZZ" ;
                    }
                    return field.getName();
                }
            }) ;
  4. 忽略掉某些 Javabean 的屬性

    // 使用關鍵字 transient 在構建 JSON 的時候,會忽略掉該屬性
      private transient String password;
  5. 支持解析日期

    設定日期解析格式 ;

    // 建立一個 支持解析日期 的 gson
            Gson gson = new GsonBuilder().setDateFormat("yyyy-mm-dd").create() ;
  6. 支持 JSON Array 數組到 java 集合類的無縫轉換

    說的是,對於 JSONArray 數組,咱們在 java 裏面是能夠直接用 集合 接收的, GSON 會自動的轉換 ;

相關文章
相關標籤/搜索