Android 中 轉換 JSON 的 工具 -GSON – 廖時賢 – Medio

何謂 JSON

JSON , 全 名 是 JavaScript Object Notation , 是 一種 輕量級 的 資料 交換 格式 , 而 從 名稱 可以 得知 他 是 從 JavaScript 中 衍生 出來 的 , 而 其中 包含 的 格式 只有 2 種 – 物件 (Object) 和 陣列Matriz) , 下面 講 一下 這 兩者 的 差異。

物件 (Objeto)

在 JavaScript 中 , 物件 的 表示 法 是 用 大 括號 {} 將 資料 包 起來 , 其 的 中 的 資料 則 是 鍵 – 值 對 (par clave-valor) , 每個 鍵 一定 都是 字串 , 而 值 可以 是數值 、 字串 、 布林 或者 是 null , 鍵 – 值 對 之間 用 逗號 «,» 做 區隔 , 範例 如下

{
"name" : "John",
"age" : 18,
"handsome" : true,
"rich" : false,
"girlFriend" : null
}

在 , 的 範例 中 建立 了 一個 Objeto JSON , 名字 叫 John , 年齡 18 歲 , 很帥 但 不 富有 , 沒有 女朋友 (純屬 範例 , 叫 John 不要 生氣 😅) ; 而 Objeto JSON , 特性 是 的 的各個 par clave-valor 是 不需要 按照 順序 給 的 , 所以 就算 先 定義 年齡 再 定義 名字 , 還是 可以 視 作為 的 Objeto JSON ; 而 因為 資料 都是 一個 clave 對 到 一個 valor , 因此 可以 透過 呼叫 這個 物件 裡面 的Clave (比如 «nombre») 得到 在 這個 物件 中 對應 的 值 («Juan»)。

陣列 (matriz)

JavaScript 中 陣列 的 表示 法 是 用 中 括號[]包 起來 , 裡面 的 資料 只有 值 , 可以 用 的 類型 跟 Objeto 一樣 , 有 數值 、 字串 、 布林 或者 null , 每個 值 之間 同樣 用 逗號 做 區隔 , 舉例 如下

[
1,
"demo",
true,
null
]

在 這個 範例 中 建立 了 一個 JSON Array, 與 JSON Object 不同, JSON Array 值 的 順序 是 不能 變動 的 , 因為每個 值 有 對應 到 一個 索引 (índice), 所以 如果 呼叫 這個 陣列 中 的 第 0 項 , 是 可以 得到 1 這個 值 的。

而 物件 和 陣列 是 可以 包含 彼此 的 , 比如

[  
{
"name":"Ram",
"email":"[email protected]",
"sports":[
"basketball",
"soccer"
]
},
{
"name":"Bob",
"email":"[email protected]",
"sports":[
"baseball",
"swimming"
]
}
]

上面 的 範例 中 , 在 一個 JSON Array 中 包含 了 兩個 JSON Object , 而 每個 Object 有 name 、 email 、 sports 這 3 個 鍵 , 其中 sports 的 值 是 另一個 JSON Array。

Android 中 的 JSON 轉換

開頭 提到 , 在 Android 中 有 內建 支援 JSON 的 轉換 , 因此 這邊 先講 一下 怎麼 透過 內建 的 轉換 JSON。

假設 有 一個 clase de datos 用來 儲存 學生 的 數學 和 英文 成績

如果 有 一個 學生 Tom , 數學 85 分 , 英文 90 分 , 當 要 透過 JSON 格式 將 Tom 的 成績 上傳 時 , 可以 透過 org.json 這個 package 來 將 data class 轉換 成 JSON 字串 來 上傳

這時 如果 把 jsonStr 打印 出來 , 可以 得到 這樣 一個 字串

"{"name":"Tom","math":85,"english":90}"

這時 就 可以 將 這筆 資料 上傳 了 ; 反過來 說 , 如果 透過 網路 得到 了 Mary 這 名 學生 的 的 字串 , 要將 他 轉換 成 Clase de datos del estudiante 則 是 這樣 做

先將 JSON 字串 轉換 成 JSONObject , 再 透過 每個 key 從 JSONObject 中 撈 資料 出來 , 建立 的 的 Student 實體 , 最後 可以 得到 一個 Student 實體

Student(name=Mary, math=95, english=76)

看起來 這樣 就 完成 了 不是 嗎?注意 在 上面 的 例子 中 , 因為 Student 只有 3 樣 資料 , 所以 在 得到 JSON 資料 並 轉換 成 Student 時 沒甚麼 大 問題 , 但 試想 如果 今天 data class 裡面 包 了 10 幾 樣 數據 呢?這 時候 透過 clave 取得 valor 的 這個 步驟 就 需要 在 解析 JSON 字串 時 重複 10 幾次 , 不但 很 耗時間 、 造成 código 不 簡潔 、 甚至 如果 取得 目標 數值 的 類別 錯誤 時又 需要 去看 到底 是 哪個 值 取錯 , 選擇 正確 的 方法 ; 為了 解決 這些 問題 , Gson 就是 一個 不錯 的 工具。

使用 Gson 來做 JSON 轉換

首先 將 Gson Library 加入 APP 層級 的 dependencias

implementation 'com.google.code.gson:gson:2.8.6'

當 要用 到 JSON 轉換 的 時候 , 只要 建立 一個 新 的 Gson 實體 , 就 可以 透過 這個 實體 來 幫忙 轉換

回到 先前 的 例子 , 假設 要 在 Estudiante 這個 clase de datos 跟 JSON 格式 之間 做 轉換 , 那 上面 這段 程式 碼 就會 變成

跟 上面 使用 內建 的 paquete json 相比 , 使用 Gson 是 不是 相對 簡單 很多 呢。

@SerializedName

有時候 從 網路 上 得到 的 JSON 資料 和 我們 自 訂 的 clase de datos 欄 位 名稱 不 一樣 , 如果 直接 的 的 會 出錯 , 這 時候 就 可以 透過 SerializedName 這個 註解 來 幫忙 在 在 Gson 文件 中 對於 這個 註解

An annotation that indicates this member should be serialized to JSON with the provided name value as its field name.

也就是說 , 當 有 設置 SerializedName 註解 , Gson 在 做 轉換 的 時候 會將 特定 參數 的 轉換 成 設置 的 名稱 , 直接 舉例 來看 , 上面 Clase de datos del estudiante 中 有 一個 參數 name , 但 網路 上 的 資料 不是 叫name 而是 叫 studentName , 那就 可以 在 Student data class 中 加上 註解

當 要把 Student 這個 data class 轉換 成 JSONObject 時 , 本來 叫做 name 的 參數 會 轉換 成 studentName 這個 欄 位 , 反過來 說 , 當 得到 JSONObject 中 有 studentName 這個 欄 位 時 , 中 轉換 中 會 的 其他 ;沒有 特別 註解 的 則 是 本來 叫 甚麼 , 轉換 後 還是 叫 甚麼。

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *