JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式
起源
- 数据标记,存储,传输
- 读写速度快
- 解析简单
- 轻量级
- 独立于语言,平台
- 具有自我描叙性
组成
key/value 的形式存在
- key: 以正常string 的为Key ,并且不支持null
- value:值(value)可以是双引号括起来的字符串(string)、数值(number)、 true 、 false 、 null 、对象 (object)或者数组(array)。这些结构可以嵌套
使用
Android Studio自带org.json解析
- 解析原理:序列化,基于文档驱动,需要把全部文件读入到内存中,然后遍历所有数据,根据需要检索想要的数据(想要哪个取哪个速度更快)
- 生成json
//生成JSON private void createJson(Context context) throws Exception { File file = new File(getFilesDir(), "orgjson.json");
//获取到应用在内部 的私有文件夹下对应的orgjson.json文件
JSONObject student = new JSONObject();
//实例化一个JSONObject对象
student.put("name", "OrgJson");
//对其添加一个数据 student.put("sax", "男");
student.put("age", 23);
JSONObject course1 = new JSONObject();
course1.put("name", "语文");
course1.put("score", 98.2f);
JSONObject course2 = new JSONObject();
course2.put("name", "数学");
course2.put("score", 93.2f);
JSONArray coures = new JSONArray();
//实例化一个JSON数组
coures.put(0, course1);
//将course1添加到JSONArray,下标为0
coures.put(1, course2);
//然后将JSONArray添加到名为student的JSONObject
student.put("courses", coures);
FileOutputStream fos = new FileOutputStream(file); fos.write(student.toString().getBytes());
fos.close();
Log.i(TAG, "createJson: " + student.toString());
Toast.makeText(context, "创建成功", Toast.LENGTH_LONG).show();
- 读取文件
File file = new File(getFilesDir(), "orgjson.json");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line; StringBuffer sb = new StringBuffer();
while (null != (line = br.readLine())) { sb.append(line); }fis.close(); isr.close(); br.close(); Student student = new Student(); //利用JSONObject进行解析 JSONObject stuJsonObject = new JSONObject(sb.toString());
//为什么不用getString?
//optString会在得不到你想要的值时候返回空字符串"",而getString会抛出异常 String name = stuJsonObject.optString("name", "");
student.setName(name);
student.setSax(stuJsonObject.optString("sax", "男")); student.setAge(stuJsonObject.optInt("age", 18));
//获取数组数据 JSONArray couresJson = stuJsonObject.optJSONArray("courses");
for (int i = 0; i < couresJson.length(); i++) {
JSONObject courseJsonObject = couresJson.getJSONObject(i);
Course course = new Course(); course.setName(courseJsonObject.optString("name", "")); course.setScore((float) courseJsonObject.optDouble("score", 0)); student.addCourse(course);
}
Log.i(TAG, "parseJson: " + student); Toast.makeText(context, "解析成功", Toast.LENGTH_LONG).show(); } 262728293031323334353637383940414243444546474849505152535455565758596061
Gson 解析
解析原理:基于事件驱动
解析流程:根据所需取的数据 建立1个对应于JSON数据的JavaBean类,即可通过简单操作解析出 所需数据
Gson 不要求JavaBean类里面的属性一定全部和JSON数据里的所有key相同,可以按需取数据 具体实现
- JsonElement(类似于xml 的Element,是对于元素的解析) 其为:null(JsonNull);JsonObject,JsonArray,JsonPrimitive,JsonNull都是JsonElement这个抽象类的子类,每个Json 的节点元素都是都能对应上其中一个类型
如果需要特殊的json type,可以通过自定义的typeAdapter 来适配特殊类型
FastJson
goson 很像不再细说
Jackson
事件驱动解析,但是需要Java bean 和对应的json key 值对应
所有的解析库都遵守的规则是:
- 构词规则:即为json 的组成语法,
- 语法分析:jsonToken/jsontype 有辅助枚举类型匹配当,当不在其中时候,抛出异常, 符合规则生成token 序列串用于用于数据保存
面试
- Expected BEGIN_ARRAY but was STRING at line 1 column 27
- 让返回null即可解决问题
- 用Gson自带的解决方案
static class AuthorDeserializer implements JsonDeserializer {
@Override
public Object deserialize(
JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final GsonError1.AuthorsBean author = new GsonError1.AuthorsBean(); author.setId(jsonObject.get("id").getAsString());
author.setName(jsonObject.get("name").getAsString());
return author;
}
}