我想无论是只要是做Android开发的相信都对于JSON都不会陌生,一般从服务器端传过来的数据返回到客户端的数据格式一般可分为HTML、XML和JSON 这三种格式,其中XML和JSON两种格式的数据都属于轻量级的数据,也许是因为JSON与Javascript交互更方便、传输速度更快、体积更小,所以绝大部分都会采用JSON作为传输数据的主要格式。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。它是基于 JavaScript Programming Language , Standard ECMA-262 3rd Edition - December 1999 的一个子集。 JSON采用完全独立于程序语言的文本格式,但是也使用了类C语言的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。本质上JSON就是一串由“{”、“}”、“[”、“]”、“:”、“,”按照一定规范与其他字符串组合到一起的特殊格式的字符串。
数据在键/值对中 ,且如果键和值是字符串,那不管是键和值都要用双引号引起来。
数据由逗号分隔 ,每个键值对之间和每个数组或对象之间都由逗号分隔
花括号保存对象 ,单个对象最外层由花括号包裹。
方括号保存数组,多个对象最外层由方括号包裹。
JSON 数据的是若干个由键/值对来表示的,键/值对包括字段名称(即键,必须是包裹在双引号中的字符串),键紧跟一个冒号,然后是值(值的数据类型可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)),总之,“” 双引号内是键(又叫为属性)或值。
"key":value
JSON对象(object) 是由花括号包裹起来的若干个的键值对的集合。(一个对象以“{”(左花括号)开始,“}”(右花括号)结束,每个键值对之间使用“,”(逗号)分隔)
{
"userimfo":
{"blog":"csdn" , "user":"CrazyMo_","age":1 ,"isWorking":true}
}
JSON 数组是由方括号包裹的若干个对象的集合(一个数组以“[”(左中括号)开始,“]”(右中括号)结束。对象之间使用“,”(逗号)分隔)。数组是用于存储多个对象的。
{
"employees": [
{ "firstName":"Mo" , "lastName":"Crazy" },
{ "job":"android" }
]
}
JSON一共有两种数据结构,一种是以键值对集合形式存在的无序的JSON对象,另一种是以无序的JSON对象集合存在的JSON数组,所以JSON的结构基本上就是这两种元素之间的互相嵌套。
Android原生的JSON解析相关类都放在org.json包下,主要涉及到五个类:JSONObject、JSONArray、JSONStringer、JSONTokener、JSONException。
作为JSON的基本单元,其包含一对键值对。它对外部调用的响应体现为一个标准的字符串(如调用toString()方法输出的数值时直接输出完整的JSON格式的字符串),但其对于内部行为的操作格式略微不同(如初始化一个JSONObject实例,引用内部的put()方法添加数值:new JSONObject().put(“JSON”, “Hello,World!”))。
部分方法 | 说明 |
---|---|
JSONObject() | 构造 |
JSONObject(String json) | 通过JSON字符串构造JSONObject |
JSONObject(Map map) | 通过Map构造JSONObject |
JSONObject(JSONTokener tokener) | 通过JSON字符串构造JSONObject |
Object get(String name) | 返回键对应的值对象,如果不存在这样的映射,则抛出异常 |
Object opt(String name) | 返回键对应的值对象,如果不存在这样的映射,则返回null |
JSONObject getJSONObject(String name) | 返回键对应的键值对 |
JSONArray getJSONArray(String name) | 返回键对应的数组 |
JSONObject put(String name, double value) | 输入键值对 |
它对外部调用的响应体现为一个标准的字符串,当然这个类的内部同样具有查询行为,get()和opt()两种方法都可以通过index索引返回指定的数值,put()方法用来添加或者替换数值。
部分方法 | 说明 |
---|---|
JSONArray() | 构造 |
JSONArray(String json) | 通过JSON字符串构造JSONArray |
JSONArray(Collection map) | 通过集合构造JSONArray |
JSONArray(JSONTokener tokener) | 通过JSON字符串构造JSONArray |
Object get(int index) | 返回索引对应的对象, |
Object opt(String name) | 返回键对应的值对象,如果不存在这样的映射,则返回null |
JSONObject getJSONObject(int index) | 返回所以对应的键值对 |
JSONArray getJSONArray(String name) | 返回索引对应的数组 |
JSONArray put(int index, Object value) | 在指定索引处设置值 |
通过这个类可以帮助我们快速和便捷的创建JSON字符串。其最大的优点在于可以减少由于 格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则创建JSON 字符串。每个JSONStringer实体只能对应创建一个JSON 字符串其最大的优点在于可以减少由于格式的错误导致程序异常。
部分方法 | 说明 |
---|---|
JSONStringer() | 构造犯法 |
JSONStringer array() | 构造数组开始标志“[” |
JSONStringer endArray() | 构造数组结束标志“[” |
JSONStringer object() | JSONObject开始标志“{” |
JSONStringer endObject() | JSONObject结束标志“}” |
JSONStringer key(String name) | 设置键 |
JSONStringer value(Object value) | 设置值 |
我们可以利用这个类实现遍历JSON字符串、跳转到指定位置处开始遍历等操作。
部分方法 | 说明 |
---|---|
JSONTokener(String in) | 通过JSON字符串构造 |
Object nextValue() | 返回下一个对象 |
char next() | 逐一遍历字符,执行一次往下移一位 |
String next(int length) | 返回输入字符串中的下一个指定长度的字符。 |
void back() | 往回移一位 |
void skipTo(char c) | 移动刀指定字符c第一次出现的位置处 |
- JSONException——JSON中用到的异常类
以创建{“UserImfo”:{“contact”:[“0218989”,”1565367234”],”name”:”CrazyMo_”,”age”:1,”address”:{“country”:”CN”,”province”:”SH”}}}为例
//使用JSONObject和JSONArray创建JSON字符串
try {
//最外层是{},所以这数据对应的就是一个对象
JSONObject user=new JSONObject();
// 次外层是{},是创建一个对象
JSONObject person = new JSONObject();
// 第一个键contact的值是[]对应数组,再创建数组对象
JSONArray contact = new JSONArray();
contact.put("0218989").put("1565367234");
//这个contact对应的值是数组
person.put("contact", contact);
person.put("name", "CrazyMo_");
person.put("age", 1);
// 键address的值是对象,所以又要创建一个对象
JSONObject address = new JSONObject();
address.put("country", "CN");
address.put("province", "SH");
person.put("address", address);
user.put("UserImfo",person);
Log.e("JSON",user.toString());
} catch (JSONException ex) {
// 键为null或使用json不支持的数字格式(NaN, infinities)
throw new RuntimeException(ex);
}
JSONStringer其实有点类似是XML的创建,通过定义开始标志和结束标志来合成JSON字符串,与上面JSONObject和JSONArray方式不同之处在于,当值是对象的时候,JSONStringer不需要手动去设置,他会自动通过endObject来封装。
try {
JSONStringer jsonStringer = new JSONStringer();
jsonStringer.object(); // 首先是{,对象开始。object和endObject必须配对使用
jsonStringer.key("UserImfo");
jsonStringer.object();
jsonStringer.key("contact");
// 键contact的值是数组。array和endArray必须配对使用
jsonStringer.array();
jsonStringer.value("0218989").value("1565367234");
jsonStringer.endArray();
jsonStringer.key("name");
jsonStringer.value("CrazyMo_");
jsonStringer.key("age");
jsonStringer.value(1);
jsonStringer.key("address");
// 键address的值是对象
jsonStringer.object();
jsonStringer.key("country");
jsonStringer.value("CN");
jsonStringer.key("province");
jsonStringer.value("SH");
jsonStringer.endObject();
jsonStringer.endObject(); // },次外层对象结束
jsonStringer.endObject();//最外层对象结束
Log.e("JSON",jsonStringer.toString());
} catch (JSONException ex) {
throw new RuntimeException(ex);
}
基本思想就是用JSONObject 解析”{}”,用JSONArray来解析”[]”。
private void parseJSON() {
try {
String strResult="{\"UserImfo\":{\"contact\":[\"0218989\",\"1565367234\"],\"name\":\"CrazyMo_\",\"address\":{\"country\":\"CN\",\"province\":\"SH\"}}}";
JSONObject jsonObj = new JSONObject(strResult).getJSONObject("UserImfo");//键UserImfo对应的值是一个对象所以用JSONObject来存储
Log.e("JSON",jsonObj.toString());
JSONArray array=jsonObj.getJSONArray("contact");//键contact对应的值是一个数组所以用JSONArray来存储
Log.e("JSON", array.opt(0)+","+array.opt(1));
String name = jsonObj.getString("name");//键name对应的值是一个字符串
JSONObject address = jsonObj.getJSONObject("address");
Log.e("JSON","姓名:" + name + "国籍:" + address.get("country")+"省份"+address.get("province"));
} catch (JSONException e) {
System.out.println("Json parse error");
e.printStackTrace();
}
}
下一篇总结使用第三方开源库解析JSON。