JSON文件的应用——记录类型的用户数据存储

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mr_Megamind/article/details/85275002

前提

之前一直有个问题没有弄清楚,就是“记录类型的用户数据是如何存储的”。经过搜索、学习和思考,现在终于弄清楚了。因此有了这篇博文。


从问题出发

问题其实前面已经说了,我们再具体一些。比如我们玩一个游戏,游戏里面每个玩家都有“背包”, 如果这个“背包”的容量很大(比如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类文件的那种“映射”。因此就决定都自己写吧。

希望可以给大家做一个参考。如果你知道有现成的框架可以做这件事,请告诉我,谢谢!

猜你喜欢

转载自blog.csdn.net/Mr_Megamind/article/details/85275002
今日推荐