1. 程式人生 > >JSON檔案的應用——記錄型別的使用者資料儲存

JSON檔案的應用——記錄型別的使用者資料儲存

章節索引

前提

之前一直有個問題沒有弄清楚,就是“記錄型別的使用者資料是如何儲存的”。經過搜尋、學習和思考,現在終於弄清楚了。因此有了這篇博文。


從問題出發

問題其實前面已經說了,我們再具體一些。比如我們玩一個遊戲,遊戲裡面每個玩家都有“揹包”, 如果這個“揹包”的容量很大(比如1000格),甚至是沒有限制,玩家獲得多少道具,揹包就可以多大。

從開發者的角度來看,該怎麼實現?有限的1000個,不會有人想在資料庫建1000個列用來儲存1000格上的道具吧。 那更進一步,無限揹包怎麼實現呢? 這就是我們的問題,引申一下, 這類使用者的揹包、消費記錄、通話記錄、聊天記錄等記錄型別的資料是怎麼儲存的呢?


JSON和XML

經過一番查詢,目前業內用於儲存這類記錄資料的方式不限於以下兩種:即儲存在JSON或者XML這類有結構的檔案中。
以下是一個用XML儲存資料的簡單例子:

<?xml version="1.0" ?>
	<user>
		<field id="name">
			<value>David</
value
>
</field> <field id="country"> <value>China</value> </field> <field id="email"> <value>[email protected]</value> </field> </user>

專精JSON

因為後臺請求的響應一直在用JSON,所以就專精JSON吧,我們的使用者記錄也用它來做。
上述問題中,我們主要想要實現的就是一個“無限陣列”,或者Java中的ArrayList這樣一種結構

,下面看一個簡單的例子:

{
  "contacters": [
    {
      "id": "10101",
      "name": "張三",
      "age": 22
      "singleOrNot": true
    },
    {
      "id": "10102",
      "name": "李四",
      "age": 24
    }
  ]
}

根據JSON的語法規則,方括號[ ]用來定義陣列,兩個陣列元素之間用逗號隔開。
如程式碼中所示,contacters是一個數組,裡面存了兩個聯絡人張三李四


JSON檔案讀與寫

說到底,這些資料是存在JSON檔案中的,一般情況下,一個json檔案的名稱形如a.json。為了便於讀寫,我們一般將它命名為使用者ID,如193746825.json

(1)讀JSON檔案

我一般用的邏輯是,客戶端從伺服器上下載193746825.json檔案,然後讀取出其中的JSON字串。

(2)正向對映

正向對映,即將JSON字串對映為Java裡的物件,因為沒有找到可以做JSON對映的框架,所以只能自己寫,針對上述例子的正向對映程式碼如下:

        try {//注①
            JsonNode userRecode = JsonLoader.fromString(AppGlobal.userRecord);  //注②
            JsonNode contacters = userRecode.get("contacters");
            for (int i = 0; i < contacters.size(); i++) {
                JsonNode contacter = contacters.get(i);
                Contacter c = Contacter.newInstance(contacter.get("name").asText());
                c.setId(contacter.get("id").asText());  //注③
                c.setAge(contacter.get("age") == null ? -1 : contacter.get("age").asInt());
                c.setSingleOrNot(contacter.get("singleOrNot") == null ? true : contacter.get("singleOrNot").asBoolean());
                AppGlobal.CONTACTERS.add(c);  //注④
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

註釋:
①首先需要定義好一個Contacter類,裡面的屬性和JSON檔案中的屬性一致;
②userRecoed是從伺服器上下載下來的JSON字串,通過JsonLoader.fromString函式構建頂層的JSONObject,然後再進一層,讀取contacters表示的聯絡人陣列;
③id、name和age、singleOrNot的操作是有區別的,其中前兩個屬性不需要判斷存不存在,因為一個聯絡人必然具有id和名字,否則不算是一個聯絡人,但是使用者存沒有存該聯絡人的年齡和是否單身這種屬性就不一定了,因此後兩個屬性要判斷存不存在;
④對映好一個聯絡人物件,就存到全域性的聯絡人列表中去。

(3)反向對映

當用戶修改了聯絡人,我們就需要更新伺服器上的json檔案,這時就需要把上述的Java物件對映為JSON字串,這裡就需要在Contacter類裡面寫一個toString或者toJsonString函式:

    public String toJsonString() {
        StringBuilder result = new StringBuilder("{");
        result.append("\"id\": \"").append(id).append("\",");
        result.append("\"name\": \"").append(name).append("\"");
        if (-1 != age)
            result.append(",\"age\": \"").append(String.valueOf(age)).append("\"");
        if (singleOrNot)
        	result.append(",\"singleOrNot\": ").append(String.valueOf(singleOrNot));
        result.append("}");
        return result.toString();
    }

(4)寫JSON檔案

接下來就是這個流程的最後一步,資料回寫。按照我的想法,直接上傳檔案覆蓋原檔案是超級危險的操作!那麼我們就用請求的方式,把變更後的JSON字串發到伺服器,伺服器端驗證了發來的JSON字串之後再寫到相應的檔案中去。


後記

本來還想寫一下JSON的驗證,但是感覺驗證方面的篇幅也會比較長,所以決定放在下一篇博文裡來介紹。

這一片博文裡最重要的就是“正向對映”和“反向對映”的兩段程式碼。 我在網上實在沒有找到JSON的雙向對映方面的框架,最多隻能找到把JSON檔案靜態轉換為Java類檔案的那種“對映”。因此就決定都自己寫吧。

希望可以給大家做一個參考。如果你知道有現成的框架可以做這件事,請告訴我,謝謝!