简介
一、JSON简介
- JSON是一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。
- JSON是JavaScript Object Notation的缩写,是一种轻量级的数据交换形式,是一种XML的替代方案,而且比XML更小,更快而且更易于解析。因为JSON描述对象的时候使用的是JavaScript语法,它是语言和平台独立的,并且这些年许多JSON的解析器和类库被开发出来。
二、JSON 和 XML 比较
- 可读性:JSON和XML的数据可读性基本相同
- 解析:JSON和XML同样拥有丰富的解析手段
- 体积:JSON相对于XML来讲,数据的体积小
- 速度:JSON的速度要远远快于XML
- JSON与JavaScript的交互更加方便
- JSON对数据的描述性比XML较差
三、Android中的json解析包org.json中的几个类:
- JSONObject:可以看作是一个json对象,这是系统中有关JSON定义的基本单元,其包含一对 Key/Value 数值,在Key和Value之间是以逗号","分隔,Value的类型包括:JSONArray、JSONObject、Boolean、Number、String或者默认值JSONObject.NULL object 。
- JSONStringer:json文本构建类 ,根据官方的解释,这个类可以帮助快速和便捷的创建JSON text。其最大的优点在于可以减少由于格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则创建JSON text。每个JSONStringer实体只能对应创建一个JSON text。
- JSONArray:它代表一组有序的数值,将其转换为String输出所表现的形式是用方括号包裹,数值以逗号分隔,这个类的内部同样具有查询行为,get()和opt()两种方法都可以通过index索引返回指定的数值,put()方法用来添加或者替换数值。同样这个类的value类型可以包括:Boolean、JSONArray、JSONObject、Number、String或者默认值JSONObject.NULL object。
- JSONTokener:json解析类
- JSONException:json中用到的异常
四、getType和optType api方法
- getType可以将要获取的键的值转换为指定的类型,如果无法转换或没有值则抛出JSONException
- optType也是将要获取的键的值转换为指定的类型,如果无法转换或没有值则返回用户提供的或者代码内置的默认的值
代码:json的生成及解析
public class MainActivity extends Activity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
try {
JSONObject person = new JSONObject();
person.put("name", "包青天");
person.put("age", 100);
//健phone的值是JSONArray
JSONArray phone = new JSONArray();
phone.put("111").put("222");
phone.put(1, "333");//会把"222"覆盖掉
phone.put(3, "444");//直接写第四个数据,则第三个数据是null
phone.put(new JSONObject().put("tel", 1868053).put("qq", "70488"));
person.put("phone", phone);
// 键address的值是JSONObject
JSONObject address = new JSONObject();
address.put("country", "中国");
address.put("province", "河南");
address.put("city", "许昌");
person.put("address", address);
//**************************************************************************************************
String tel = "tel=" + person.getJSONArray("phone").getJSONObject(4).getString("tel") + "\n" + "qq="
+ person.getJSONArray("phone").getJSONObject(4).getInt("qq");
tv.setText(tel + "\n\n" + JsonFormatTool.formatJson(person.toString()));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
代码:json转换为集合
public class JSONutil {
/**
* 将JSON格式的字符串封装成集合,限制条件是:必须知道,且只能只对此JSON字符串进行封装
*/
public static List<Map<String, Object>> getJSONArray(String jsonString) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
try {
//若根部是JSONObject则用JSONObject封装,否则直接用JSONArray封装,这个是必须事先知道的信息,不能在代码中判断的
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray("arrayData");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
int id = item.getInt("id");
String name = item.getString("name");
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", id);
map.put("name", name);
list.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
}
代码:json的格式化
public class JsonFormatTool {
//单位缩进字符串。
private static String SPACE = " ";
/**
* 返回格式化JSON字符串。
* @param json 未格式化的JSON字符串。
* @return 格式化的JSON字符串。
*/
public static String formatJson(String json) {
StringBuffer result = new StringBuffer();
int length = json.length();
int number = 0;
char key = 0;
//遍历输入字符串。
for (int i = 0; i < length; i++) {
//1、获取当前字符。
key = json.charAt(i);
//2、如果当前字符是前方括号、前花括号做如下处理:
if ((key == ‘[‘) || (key == ‘{‘)) {
//(1)如果前面还有字符,并且字符为“:”,打印:换行和缩进字符字符串。
if ((i - 1 > 0) && (json.charAt(i - 1) == ‘:‘)) {
result.append(‘\n‘);
result.append(indent(number));
}
//(2)打印:当前字符。
result.append(key);
//(3)前方括号、前花括号,的后面必须换行。打印:换行。
result.append(‘\n‘);
//(4)每出现一次前方括号、前花括号;缩进次数增加一次。打印:新行缩进。
number++;
result.append(indent(number));
//(5)进行下一次循环。
continue;
}
//3、如果当前字符是后方括号、后花括号做如下处理:
if ((key == ‘]‘) || (key == ‘}‘)) {
//(1)后方括号、后花括号,的前面必须换行。打印:换行。
result.append(‘\n‘);
//(2)每出现一次后方括号、后花括号;缩进次数减少一次。打印:缩进。
number--;
result.append(indent(number));
//(3)打印:当前字符。
result.append(key);
//(4)如果当前字符后面还有字符,并且字符不为“,”,打印:换行。
if (((i + 1) < length) && (json.charAt(i + 1) != ‘,‘)) {
result.append(‘\n‘);
}
//(5)继续下一次循环。
continue;
}
//4、如果当前字符是逗号。逗号后面换行,并缩进,不改变缩进次数。
//这里有bug,更改为【并且当前字符后方是双引号或左大括号】************************************************************************************
if ((key == ‘,‘) && (json.charAt(i + 1) == ‘"‘ || (json.charAt(i + 1) == ‘{‘))) {
result.append(key);result.append(‘\n‘);
result.append(indent(number));
continue;
}
//5、打印:当前字符。
result.append(key);
}
return result.toString();
}
/**
* 返回指定次数的缩进字符串。每一次缩进三个空格,即SPACE。
* @param number 缩进次数。
* @return 指定缩进次数的字符串。
*/
private static String indent(int number) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < number; i++) {
result.append(SPACE);
}
return result.toString();
}
}