项目中经常会遇到类似的需要,比如网络请求需要传送json序列化字符串,那么问题就来了,json串到底怎么转换呢?下面就iOS和Android给出不同的转换实现方式。
需要转换成的json text结构体如下:
{
“Key1”: {
“key1”: “value1”
,
“key2”: “value2”
,
“key3”: “value3”
}
,
“Key2”: {
“key1”: “value1”
,
“key2”:
[
x
,
x
,
x
,
x
,
x
],
“key3”:
[
“Ix”
,
“x”
,
“x”
,
“x”
,
“x”
]
}
}
首先分析上面的结构,最外层的括号说明里面是json对象,
Key1 和
Key2 可以看作两个主键,每一个主键里面又包含了若干个键值对,键值对的值中又包含有数组,[]
分析完了结构,怎么组织数据呢?
Android
-
利用Gson来封装转化成json string.利用Gson进行转换的时候,首先需要在radle中加入库支持
compile 'com.google.code.gson:gson:2.8.1'
-
然后需要定义实体类,比如叫做JSONModel
public class JSONModel { //data and header are json key, must be same as json key definition HashMap<String, Object> Key2; HashMap<String, String> Key1; public HashMap<String, Object> getKey2() { return Key2; } public void setKey2(HashMap<String, Object> Key2) { this.Key2 = Key2; } public HashMap<String, String> getKey1() { return Key1; } public void setKey1(HashMap<String, String> Key1) { this.Key1 = Key1; } }
-
因为通过结构分析,就看到Key2中不仅仅含有string类型的数据,还有数组对象,而且是字典的形式,因此定义成为了<String, Object>类型。而Key1中所有的value都是string类型的,因此就定义为了<String, String>类型的。
-
利用gson转换,需要注意一点,就是json文本最外层的key的名称必须和实体类中定义的成员名称一致,作为后续转换生成的真实的key,比如Key1, Key2, 那么实体类中两个hashmap定义的名称就必须也是Key1, Key2
-
利用gson转换,还需要注意的一点是,最外层包含几个key,就在实体类中定义几个对应的变量,至于每一个key中包含的子key不能定义在实体类中,并且作为对象设置到实体类中,否则最终转换的结果,这个子key将会作为最外层的一级作为展示。
而后就按照普通的操作,将key中对应的数据进行本地封装
String parseResultString = ""; ArrayList<String> array1; ArrayList array2; String valueStr; //gson Gson gson = new Gson(); JSONModel model = new JSONModel(); HashMap<String, Object> key2HashMap = new HashMap<>(); key2HashMap.put("key1",valueStr); key2HashMap.put("key2",array1); key2HashMap.put("key3",array2); HashMap<String, String> key1HashMap=new HashMap<>(); key1HashMap.put("key1",value1); key1HashMap.put("key2",value2); key1HashMap.put("key2",value3); model.setKey1(key1HashMap); model.setKey2(key2HashMap); parseResultString = gson.toJson(model);
-
封装完成后,首先实例化Gson对象
-
实例化定义好的实体类
-
进行本地化封装后将最终的结果设置给实体类中对应的变量
-
利用gson方法toJson得到最终的json string
最终转换后的json string打印出来大体格式如下:
{“Key1”:{“key1″:”value1”
,
“key2″:”value2”
,
“key3″:”value3”}
,
“Key2”:{“key2”:
[
x,x,x,x,x
],
“key1″:”value1”
,
“key3”:
[
“x”
,
“x”
,
“x”,”x”,”x”
]
}}
-
其中你可以注意到了,
[
x
,x,
x,x,x
] 和
[
“x”
,
“x”
,
“x”,”x”,”x”
],一个有引号,一个没有引号,这个是因为如果value是数字类型的,那么就没有引号。
-
还有一点,有时候转换出来的json string发现有了\反斜杠,这个通常说明你使用了类似toString的处理,而往往这种处理是不需要的,或者说是错误的,直接本地封装值就ok了。
其实也可以不用创建实体类,直接封装本地数据,用同样的方式调用一样可以。使用文件通常可以比如有已知的json格式的文本文件,直接映射成json实体类来实现就可以了。
parseResultString = gson.toJson(封装数据);
-
利用系统API JSONObject来实现json字符串的转换
上面说了借助Gson来实现的方式,还有一种更简便的方式,使用系统api
本地封装过程同上,不需要再定义实体类,封装完成后,直接使用 JSONObject jsonObject = new JSONObject(data)获取json对象,最终使用toString的方式来获取转换结果即可。
HashMap<String, Object> requestParamaters = new HashMap<>(); String parseResultString = ""; ArrayList<String> array1; ArrayList array2; String valueStr; HashMap<String, Object> key2HashMap = new HashMap<>(); key2HashMap.put("key1",valueStr); key2HashMap.put("key2",array1); key2HashMap.put("key3",array2); HashMap<String, String> key1HashMap=new HashMap<>(); key1HashMap.put("key1",value1); key1HashMap.put("key2",value2); key1HashMap.put("key2",value3); requestParamaters.put(Key1, key1HashMap); requestParameters.put(Key2, key2HashMap); JSONObject jsonObject = new JSONObject(requestParamaters); fianlString = jsonObject.toString();
注意,这种方式因为不需要创建实体类,因此需要多定义一个包含最为层结构的hashmap
HashMap<String, Object> key2HashMap = new HashMap<>();
iOS
iOS 的转换成json string就基本上使用系统api即可
NSData
*jsonData
= [
NSJSONSerialization
dataWithJSONObject
:dic
options
:0
error
:
nil
];
NSString *.
finalJsonString
= [[
NSString
alloc
]
initWithData
:
jsonData
encoding
:
NSUTF8StringEncoding
];
-
首先封装本地数据,比如定义Dictionary进行封装
-
将dic进行json序列化成nsdata
-
将data最终转换成string
这一篇文章基本结束了,常遇到的问题就此可以得到解决。