Android之JSON全面解析与使用
什么是JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语
什么是JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言 (单纯的数据格式,不受语言的约束) JSON 具有自我描述性,更易理解
对于JSON的定义以及数据格式,没有什么太多的难点,这里为官网对JSON的定义。从官网描述中可以看出,JSON本身是JavaScript中对象的描述格式,后来得以推广并逐渐取代xml。
JSON和XML的比较相比 XML 的不同之处
没有结束标签(类似于键值对的形式) 更短(没有结束标签,当然短了) 读写的速度更快 能够使用内建的 JavaScript eval() 方法进行解析 使用数组 不使用保留字 原生JSON解析Android原生的解析实际上使用的JSON的一个官方jar包。对于JSON,不需要页面展示,所以使用intellij idea进行演示。
在使用之前我们需要下载org.json的jar包。对于Android 开发环境不需要下载此jar包。因为Android SDK 中已经默认包含了该jar包。
json jar 下载地址
下载完之后导入即可。
JSONObject对象解析下面看一下数据
{ "user":{ "name":"alex", "age":"18", "isMan":true } }有一个user字段,其中包含了该user的一些基本属性。那么如何解析呢?
在解析时,有一个很关键的地方:如果是{}包含,则为JSONObject对象,如果为[]则为JSONArray对象。
看到上面的例子,我们看到整个数据为JSONObject,其内部包含了一个user字段,该字段的值也是一个JSONObject对象。
public class OrgJSONTest { public static String json = "{\"user\":{\"name\":\"alex\",\"age\":\"18\",\"isMan\":true}}"; public static void main(String[] args){ JSONObject obj = new JSONObject(json);//最外层的JSONObject对象 JSONObject user = obj.getJSONObject("user");//通过user字段获取其所包含的JSONObject对象 String name = user.getString("name");//通过name字段获取其所包含的字符串 System.out.println(name); } }打印结果如下
alex可以看到获取到了相应的值。
在JSONObject对象中封装了getXXX()等一系列方法。用以获取字符串,整形等等一系列的值。
对于如上例子,完全解析user对象如下
String name = user.getString("name");//通过name字段获取其所包含的字符串 String age = user.getString("age"); boolean isMan = user.getBoolean("isMan"); System.out.println("name:"+name+"\nage:"+age+"\nisMan:"+isMan);结果如下
name:alex age:18 isMan:true这种通过getXXX的方式,无疑会出现一些问题,我们开始一一尝试。
getXXX方法获取的类型不符 字符串类型转整形对于上面的例子,我们可以看到age字段虽然其对应的值是双引号括起的字符串,但其实际上是一个整形,那么我们是否能够通过getInt获取整形呢。
int age = user.getInt("age"); age:18当然是可以得,同时字符串类型可以转化为布尔类型,整数类型,浮点型等等。但字符串的内容必须符合规范,否则会报异常。如果看其源码可知,其内部实质是调用了对应对象的parseXXX()方法进行转化操作。
//getInt源码 public int getInt(String key) throws JSONException { Object object = this.get(key); try { //关键点,如果是数值类型,则调用intValue(),否则强转成字符串之后调用parserInt方法() return object instanceof Number?((Num,ber)object).intValue():Integer.parseInt((String)object); } catch (Exception var4) { throw new JSONException("JSONObject[" + quote(key) + "] is not an int."); } } 整形等转字符串类型按照如上的思维逻辑,直接getString("xxx")就可以了。但事实正好相反,该方法,如果对应值不是双引号括起的,则会抛出异常。
//getString 源码 public String getString(String key) throws JSONException { Object object = this.get(key); //直接判断是否是字符串类型,如果不是,则抛出异常 if(object instanceof String) { return (String)object; } else { throw new JSONException("JSONObject[" + quote(key) + "] not a string."); } } getXXX(“”) 没有对应的键值通过上面的例子,可以得知getXXX("")方法是通过字段(键)获取对应的值。那么肯定存在一种情况,及没有键的存在。
System.out.println(user.getString("sex")); Exception in thread "main" org.json.JSONException: JSONObject["sex"] not found. at org.json.JSONObject.get(JSONObject.java:471) at org.json.JSONObject.getString(JSONObject.java:717) at json.OrgJSONTest.main(OrgJSONTest.java:24)果断报异常。
那么怎么办呢:使用optXXX()。后面会讲。
JSONArray 解析该对象用以解析[]的对象,及数组对象。用法类似,修改一下数据格式
{ "user":[ { "name":"alex", "age":"18", "isMan":true }, { "name":"alex", "age":"18", "isMan":true } ] }user对应的值不再是一个JSONObject对象,而是一个JSONArray对象(数组对象)。该数组对象中包含了多个JSONObject。
JSONObject obj = new JSONObject(json);//最外层的JSONObject对象 JSONArray array = obj.getJSONArray("user"); for(int i = 0 ; i.length();i++){> alex mahao解析过程与JSONObject类似,多了一个遍历JSONArray的步骤,把JSONArray当作JAVA中的数组对待使用。两者使用方式几乎一样。
构造JSON 数据对于POST请求,传参数时一般都是传入一个json数据。那么如何构造json数据呢,使用字符串拼接可以,但很蛋疼。当然,JSONObject等提供了对应的方法。
使用如下:
//外层obj对象 JSONObject objWrite = new JSONObject(); //user对象 JSONObject userWrite = new JSONObject(); //写入对应属性 userWrite.put("name","alex"); userWrite.put("age","18"); userWrite.put("isMan",true); //将user对象写入到外层obj中 objWrite.put("user",userWrite); System.out.println(objWrite); {"user":{"name":"alex","isMan":true,"age":"18"}} opt 替代 get在上面使用中,我们通过getXXX()获取相应值。但是,会发现其局限性很多,很容易就抛异常,需要我们try...catch去捕获。而optXXX()对此进行了优化。
首先看一下他的用法,在看用法之前,我们回忆之前使用get时的两个问题
其他类型转字符串类型抛出异常 当需要的字段没有时,抛出异常。