筆者前幾周在處理資料解析這塊碰到了好多的坑 這裡只討論資料解析這塊的知識
這裡並不打算直接通過object = new Gson().fromJson(json, object.getClass());
得到對應的json的實體型別
而是通過JsonParser Api對資料進行解析,方便後面講到對於複雜特殊的json串進行解析
通過上圖的程式碼片段可以清晰的看到對於一個json串,使用JsonParser api解析後,它就是一個JsonElement物件了,但是這個JsonElement到底是什麼,對應的到底是哪一類呢,看了程式碼可以知道,總共就四類,JsonNull(空串這樣的),JsonObject,JsonArray,JsonPrimitive,相信接觸過json的同學對JsonObject,JsonArray很熟悉了吧,用的最多的就是這兩個,JsonNull用的少,JsonPrimitive估計都沒有聽過吧JsonNull沒什麼好講的,自己做實驗就知道了,JsonPrimitive表示的是json串裡面的內容是基礎型別,可以看類的定義
當然了也存在特殊的情況,它也是JsonPrimitive型別
我們再看一段程式碼片段 定義了一個string變數
String json = "{\"code\":200, \"message\":\"ok\", \"data\":\"{\\\"id\\\":131,\\\"appId\\\":6,\\\"versionCode\\\":6014000}\"}";
複製程式碼
我們需要關注的是json串裡面key為“data”所對應的value,應該看得比較清楚,data的內容都帶有轉義符號,那麼我們該怎麼解析這樣的資料呢?
回答問題前,我們看看這段程式碼的執行結果,最終輸出的是
json == {"code":200, "message":"ok", "data":"{\"id\":131,\"appId\":6,\"versionCode\":6014000}"}
isJsonObject
isJsonPrimitive == true
複製程式碼
可以看到data的內容就是一個jsonPrimitive型別的,因為它在後端處理的時候,就將真實的內容給拍平了(不知道能不能用序列化描述額,總之是被轉義了,看起來就不是一個json串,而變成了一個純粹的string)
那麼在我們解析這個被轉義的字串的時候,需要把轉義符號去掉。
JsonPrimitive primitive = jsonElement.getAsJsonObject().get("data").getAsJsonPrimitive();
System.out.println("getAsString == " + primitive.getAsString());
System.out.println("toString == " + primitive.toString());
複製程式碼
得到的結果是
getAsString == {"id":131,"appId":6,"versionCode":6014000}
toString == "{\"id\":131,\"appId\":6,\"versionCode\":6014000}"
複製程式碼
看這個執行結果可以知道通過getAsString(),得到的就是一個json串,而不是還帶有轉義字元的string,這種情況下,就可以通過
App app = new Gson().fromJson(primitive.getAsJsonPrimitive().getAsString(), App.class);
得到具體的實體類模型了
以上只是簡單的情況,複雜的情況需要結合真實的實際場景來,使用標準的Gson api解析,這樣可以避免出現一些莫名其妙的問題
舉一個例子來描述這種場景:
這個程式碼片段試將後端的一個json資料轉換成了map的資料結構,我們看下結果{code=200.0, message=ok, data=dataString}
複製程式碼
發現code被轉成了200.0,變成了double型別,這個問題在這裡不深究,想深究的可以看這個https://gist.github.com/xingstarx/5ddc14ff6ca68ba4097815c90d1c47cc,以及https://stackoverflow.com/a/36529534/5279354 總之在使用Gson解析的時候,不要只知道gson.from這一個api,沒事也需要多看看Gson相關的其他api,瞭解下Gson解析的工作原理,有助於我們更好的處理這類問題
附上完整的程式碼片段
@Test
public void test2() {
String json = "{\"code\":200, \"message\":\"ok\", \"data\":\"{\\\"id\\\":131,\\\"appId\\\":6,\\\"versionCode\\\":6014000}\"}";
System.out.println("json == " + json);
JsonElement jsonElement = new JsonParser().parse(json);
if (jsonElement.isJsonNull()) {
} else if (jsonElement.isJsonObject()) {
JsonPrimitive primitive = jsonElement.getAsJsonObject().get("data").getAsJsonPrimitive();
System.out.println("getAsString == " + primitive.getAsString());
System.out.println("toString == " + primitive.toString());
App app = new Gson().fromJson(primitive.getAsJsonPrimitive().getAsString(), App.class);
// App app = new Gson().fromJson(primitive.getAsJsonPrimitive().toString(), App.class);
System.out.println(app);
} else if (jsonElement.isJsonArray()) {
} else if (jsonElement.isJsonPrimitive()) {
}
// Map<String, Object> map = new LinkedTreeMap<>();
// map = new Gson().fromJson(json, map.getClass());
// System.out.println(map);
}
複製程式碼