筆者前幾周在處理數(shù)據(jù)解析這塊碰到了好多的坑
這里只討論數(shù)據(jù)解析這塊的知識
這里并不打算直接通過object = new Gson().fromJson(json, object.getClass());
得到對應的json的實體類型
而是通過JsonParser Api對數(shù)據(jù)進行解析冀宴,方便后面講到對于復雜特殊的json串進行解析
通過上圖的代碼片段可以清晰的看到對于一個json串,使用JsonParser api解析后,它就是一個JsonElement對象了,但是這個JsonElement到底是什么繁扎,對應的到底是哪一類呢咖城,看了代碼可以知道姐呐,總共就四類漱挎,JsonNull(空串這樣的),JsonObject,JsonArray,JsonPrimitive,相信接觸過json的同學對JsonObject,JsonArray很熟悉了吧睬澡,用的最多的就是這兩個固额,JsonNull用的少,JsonPrimitive估計都沒有聽過吧
JsonNull沒什么好講的猴贰,自己做實驗就知道了对雪,JsonPrimitive表示的是json串里面的內(nèi)容是基礎類型,可以看類的定義
當然了也存在特殊的情況米绕,它也是JsonPrimitive類型
我們再看一段代碼片段
定義了一個string變量
String json = "{\"code\":200, \"message\":\"ok\", \"data\":\"{\\\"id\\\":131,\\\"appId\\\":6,\\\"versionCode\\\":6014000}\"}";
我們需要關注的是json串里面key為“data”所對應的value,應該看得比較清楚瑟捣,data的內(nèi)容都帶有轉(zhuǎn)義符號,那么我們該怎么解析這樣的數(shù)據(jù)呢栅干?
回答問題前迈套,我們看看這段代碼的執(zhí)行結(jié)果,最終輸出的是
json == {"code":200, "message":"ok", "data":"{\"id\":131,\"appId\":6,\"versionCode\":6014000}"}
isJsonObject
isJsonPrimitive == true
可以看到data的內(nèi)容就是一個jsonPrimitive類型的碱鳞,因為它在后端處理的時候桑李,就將真實的內(nèi)容給拍平了(不知道能不能用序列化描述額,總之是被轉(zhuǎn)義了窿给,看起來就不是一個json串贵白,而變成了一個純粹的string)
那么在我們解析這個被轉(zhuǎn)義的字符串的時候,需要把轉(zhuǎn)義符號去掉崩泡。
JsonPrimitive primitive = jsonElement.getAsJsonObject().get("data").getAsJsonPrimitive();
System.out.println("getAsString == " + primitive.getAsString());
System.out.println("toString == " + primitive.toString());
得到的結(jié)果是
getAsString == {"id":131,"appId":6,"versionCode":6014000}
toString == "{\"id\":131,\"appId\":6,\"versionCode\":6014000}"
看這個執(zhí)行結(jié)果可以知道通過getAsString()禁荒,得到的就是一個json串,而不是還帶有轉(zhuǎn)義字符的string角撞,這種情況下呛伴,就可以通過
App app = new Gson().fromJson(primitive.getAsJsonPrimitive().getAsString(), App.class);
得到具體的實體類模型了
以上只是簡單的情況,復雜的情況需要結(jié)合真實的實際場景來谒所,使用標準的Gson api解析热康,這樣可以避免出現(xiàn)一些莫名其妙的問題
舉一個例子來描述這種場景:
這個代碼片段試將后端的一個json數(shù)據(jù)轉(zhuǎn)換成了map的數(shù)據(jù)結(jié)構,我們看下結(jié)果
{code=200.0, message=ok, data=dataString}
發(fā)現(xiàn)code被轉(zhuǎn)成了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);
}