1. 程式人生 > 實用技巧 >【JavaWeb】JSON 檔案

【JavaWeb】JSON 檔案

JSON 檔案

什麼是 JSON

JSON(JavaScript Object Notation),即 JS 物件符號。 是一種輕量級(相對於 XML 來說)的資料交換格式,易於閱讀和編寫,同時也易於機器解析和生成。JSON 採用完全獨立於語言的文字格式,而且很多語言都提供了對 JSON 的支援,也有很多優秀的第三方庫,這使得 JSON 成為理想的資料交換格式。其中資料交換指的是客戶端和伺服器之間的業務資料的傳遞格式。

JSON 在 JS 中的使用

JSON 的定義

  • 由鍵值對組成,並且由花括號包圍
  • 每個鍵由引號引起來
  • 鍵和值之間使用冒號進行分隔,多組鍵值對之間進行逗號進行分隔
var jsonObj = {
    "key1": 12,
    "key2": "abc",
    "key3": true,
    "key4": [11, "arr", false],
    "key5": {
        "key5_1": 551,
        "key5_2": "key5_2_value"
    },
    "key6":[{
        "key6_1_1": 6611,
        "key6_1_2": "key6_1_2_value"
        }, {
        "key6_2_1": 6621,
        "key6_2_2": "key6_2_2_value"
    }]
};

JSON 的訪問

  • 它本身是一個物件,其中的 key 可以理解為是物件中的一個屬性
  • key 訪問就跟訪問物件的屬性一樣: JSON 物件.key
alert(typeof(jsonObj));// object, 說明 json 就是一個物件
alert(jsonObj.key1); // 12
alert(jsonObj.key2); // abc
alert(jsonObj.key3); // true
alert(jsonObj.key4);// 得到陣列[11,"arr",false]

// json 中 陣列值的遍歷
for(var i = 0; i < jsonObj.key4.length; i++) {
    alert(jsonObj.key4[i]);
}

alert(jsonObj.key5.key5_1);//551
alert(jsonObj.key5.key5_2);//key5_2_value
alert(jsonObj.key6 );// 得到 json 陣列

// 取出來每一個元素都是 json 物件
var jsonItem = jsonObj.key6[0];
// alert( jsonItem.key6_1_1 ); //6611
alert( jsonItem.key6_1_2 ); //key6_1_2_value

JSON 的常用方法

  • JSON 的存在形式:
    • 物件的形式存在,稱作 JSON 物件,操作 JSON 中的資料時需要這種形式
    • 字串的形式存在,稱作 JSON 字串,在客戶端和伺服器之間進行資料交換時需要這種形式
  • JSON.stringfy() 把 JSON 物件 轉換為 JSON 字串
  • JSON.parse() 把 JSON 字串 轉換為 JSON 物件
// 把 json 物件轉換成為 json 字串
var jsonObjString = JSON.stringify(jsonObj); // 特別像 Java 中物件的 toString
alert(jsonObjString)

// 把 json 字串轉換成為 json 物件
var jsonObj2 = JSON.parse(jsonObjString);
alert(jsonObj2.key1);// 12
alert(jsonObj2.key2);// abc

JSON 在 Java 中的使用

這裡以 gson 為例。

JavaBean 和 JSON 的互轉

package cn.parzulpan.test;

import cn.parzulpan.bean.User;
import com.google.gson.Gson;

/**
 * @Author : parzulpan
 * @Time : 2020-12-14
 * @Desc : JavaBean 和 JSON 的互轉
 */

public class JavaBeanAndJSON {
    public static void main(String[] args) {
        // 建立 JavaBean 物件
        User user = new User(1, "parzulpan", "123456", "[email protected]");
        // 建立 Gson 物件
        Gson gson = new Gson();

        // toJson 方法可以把 java 物件轉換成為 json 字串
        String userJsonString = gson.toJson(user);
        System.out.println(userJsonString);

        // fromJson 把 json 字串轉換回 Java 物件
        // 第一個引數是 json 字串
        // 第二個引數是轉換回去的 Java 物件型別,對於 JavaBean 可以直接 .class
        User user1 = gson.fromJson(userJsonString, User.class);
        System.out.println(user1);
    }
}

List 和 JSON 的互轉

package cn.parzulpan.test;

import cn.parzulpan.bean.User;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;

/**
 * @Author : parzulpan
 * @Time : 2020-12-14
 * @Desc : List 和 JSON 的互轉
 */

public class ListAndJSON {
    public static void main(String[] args) {
        ArrayList<User> userList = new ArrayList<>();
        userList.add(new User(1, "parzulpan", "123456", "[email protected]"));
        userList.add(new User(null, "tom", "214531", "[email protected]"));

        Gson gson = new Gson();

        // 把 List 轉換為 JSON 字串
        String userListJsonString = gson.toJson(userList);
        System.out.println(userListJsonString);

        // 把 JSON 字串 轉換為 List,對於集合,第二個引數需要 Type typeOfT
        // 為了確保範型,需要實現一個類繼承 TypeToken
        System.out.println(new UserListType().getType());   // class java.util.ArrayList
        System.out.println(new UserListType().getRawType());    // class cn.parzulpan.test.UserListType
        ArrayList<User> list = gson.fromJson(userListJsonString, new UserListType().getType());
        System.out.println(list);
        User user = list.get(0);
        System.out.println(user);
    }
}

class UserListType extends TypeToken<ArrayList<User>> {

}

Map 和 JSON 的互轉

package cn.parzulpan.test;

import cn.parzulpan.bean.User;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author : parzulpan
 * @Time : 2020-12-14
 * @Desc : Map 和 JSON 的互轉
 */

public class MapAndJSON {
    public static void main(String[] args) {
        Map<Integer, User> userMap = new LinkedHashMap<>();

        userMap.put(1, new User(1, "parzulpan", "123456", "[email protected]"));
        userMap.put(2, new User(null, "tom", "214531", "[email protected]"));

        Gson gson = new Gson();

        String userMapJsonString = gson.toJson(userMap);
        System.out.println(userMapJsonString);

//        Map<Integer, User> userMap1 = gson.fromJson(userMapJsonString, new UserMapType().getType());
        // 或者用匿名類,推薦這種做法
        Map<Integer, User> userMap1 = gson.fromJson(userMapJsonString, new TypeToken<LinkedHashMap<Integer, User>>() {
        }.getType());

        System.out.println(userMap1);
        User user = userMap1.get(1);
        System.out.println(user);
    }
}

class UserMapType extends TypeToken<LinkedHashMap<Integer, User>> {

}

開源類庫

gson

Gson 是目前功能最全的 Json 解析神器,Gson 當初是為 Google 公司內部需求而由 Google 自行研發而來,但自從在 2008 年五月公開發布第一版後已被許多公司或使用者應用。

Gson 的應用主要為 toJson 與 fromJson 兩個轉換函式,無依賴,不需要例外額外的 jar,能夠直接跑在 JDK 上。

在使用這種物件轉換之前,需先建立好物件的型別以及其成員才能成功的將 JSON 字串成功轉換成相對應的物件。類裡面只要有 get 和 set 方法,Gson 完全可以實現複雜型別的 json 和 bean 的相互轉換轉換。

public class GsonUtil {
    private static Gson gson = new GsonBuilder().create();

    public static String bean2Json(Object obj) {
        return gson.toJson(obj);
    }

    public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
        return gson.fromJson(jsonStr, objClass);
    }

    public static String jsonFormatter(String uglyJsonStr) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        JsonParser jp = new JsonParser();
        JsonElement je = jp.parse(uglyJsonStr);
        return gson.toJson(je);
    }
}

fastjson

Fastjson 是一個 Java 語言編寫的高效能的 JSON 處理器,由阿里巴巴公司開發。無依賴,不需要例外額外的 jar,能夠直接跑在JDK上。

FastJson 在複雜型別的 Bean 轉換 Json 上會出現一些問題,可能會出現引用的型別,導致 Json 轉換出錯,需要制定引用。FastJson 採用獨創的演算法,將 parse 的速度提升到極致,超過所有 json 庫。

public class FastJsonUtil {
    public static String bean2Json(Object obj) {
        return JSON.toJSONString(obj);
    }

    public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
        return JSON.parseObject(jsonStr, objClass);
    }
}

jackson

Jackson 社群相對比較活躍,更新速度也比較快,從 Github 中的統計來看,Jackson 是最流行的 json 解析器之一,Spring MVC 的預設 json 解析器便是 Jackson。

Jackson 的核心模組由三部分組成:

  • jackson-core 核心包,提供基於”流模式”解析的相關 API,它包括 JsonPaser 和 JsonGenerator。Jackson 內部實現正是通過高效能的流模式 API 的 JsonGenerator 和 JsonParser 來生成和解析 json
  • jackson-annotations 註解包,提供標準註解功能
  • jackson-databind 資料繫結包,提供基於”物件繫結” 解析的相關 API( ObjectMapper )和”樹模型” 解析的相關 API(JsonNode);基於”物件繫結” 解析的 API 和”樹模型”解析的 API 依賴基於”流模式”解析的 API
public class JacksonUtil {
    private static ObjectMapper mapper = new ObjectMapper();

    public static String bean2Json(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
        try {
            return mapper.readValue(jsonStr, objClass);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

練習和總結