• 09.Json语法


    一. 定义

    JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式

    二. 作用

    数据标记,存储,传输

    三. 特点

    1. 读写速度快

    2. 解析简单

    3. 轻量级

    4. 独立于语言、平台

    5. 具有自我描叙性

    四. 语法

    1.JSON建构于两种结构

    • “名称/对的集合(A collection of name/value pairs)不同的语言中,它被理解为对象(object),纪录(record)

    结构(struct)、字典(dictionary)哈希表(hash table),有键列表(keyed list) 或者 关联数组(associative array)

    • 值的有序列表(An ordered list of values)在大部分语言中,它被理解为数组(array)这些都是常见的数据结构,

    事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式 在同样基于这些结构的编程语言之间交换成为可能。

    2.JSON具有以下这些形式

    1>对象

    一个无序的“‘名称/集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。

    每个名称后 跟一个“:”(冒号);“‘名称/之间使用“,”(逗号)分隔。

    1. {
    2. "name":"英语",
    3. "score": 80
    4. }

    2>数组

    是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用 “,”(逗号)分隔。

    1. "courses" : [
    2. {
    3. "name":"英语",
    4. "score": 80
    5. },
    6. {
    7. "name":"数学",
    8. "score": 90
    9. }
    10. ]

    3>值(value)

    可为双引号括起来的字符串(String),数值,true/false,null, 对象(object)或者数组(array)。这些结构可以嵌套。

    1. {
    2. "url": "https://qqe2.com",
    3. "name": "欢迎使用JSON在线解析编辑器",
    4. "array": {
    5. "JSON校验": "http://jsonlint.qqe2.com/",
    6. "Cron生成": "http://cron.qqe2.com/",
    7. "JS加密解密": "http://edit.qqe2.com/"
    8. },
    9. "boolean": true,
    10. "null": null,
    11. "number": 123,
    12. "object": {
    13. "a": "b",
    14. "c": "d",
    15. "e": "f"
    16. }
    17. }

    4>字符串(string)

    是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string);

    1. {
    2. "name" : "Zero",
    3. }

    5>数值(number)

    • 与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

    1. {
    2. "age" : 28
    3. }

    3.JSON的解析方式

    1> org.json解析

    • 解析原理:基于文档驱动,需要把全部文件读入到内存中,然后遍历所有数据,根据需要检索想要 的数据

    • 具体使用(Android Studio自带)

    1>生成JSON

    1. //生成JSON
    2. private void createJson(Context context) throws Exception {
    3. File file = new File(getFilesDir(), "orgjson.json");//获取到应用在内部 的私有文件夹下对应的orgjson.json文件
    4. JSONObject student = new JSONObject();//实例化一个JSONObject对象
    5. student.put("name", "OrgJson");//对其添加一个数据
    6. student.put("sax", "男");
    7. student.put("age", 23);
    8. JSONObject course1 = new JSONObject();
    9. course1.put("name", "语文");
    10. course1.put("score", 98.2f);
    11. JSONObject course2 = new JSONObject();
    12. course2.put("name", "数学");
    13. course2.put("score", 93.2f);
    14. JSONArray coures = new JSONArray();//实例化一个JSON数组
    15. coures.put(0, course1);//将course1添加到JSONArray,下标为0
    16. coures.put(1, course2);
    17. //然后将JSONArray添加到名为student的JSONObject
    18. student.put("courses", coures);
    19. FileOutputStream fos = new FileOutputStream(file);
    20. fos.write(student.toString().getBytes());
    21. fos.close();
    22. Log.i(TAG, "createJson: " + student.toString());
    23. Toast.makeText(context, "创建成功", Toast.LENGTH_LONG).show();
    24. }

    2>解析JSON

    1. //解析JSON
    2. private void parseJson(Context context) throws Exception {
    3. File file = new File(getFilesDir(), "orgjson.json");
    4. FileInputStream fis = new FileInputStream(file);
    5. InputStreamReader isr = new InputStreamReader(fis);
    6. BufferedReader br = new BufferedReader(isr);
    7. String line;
    8. StringBuffer sb = new StringBuffer();
    9. while (null != (line = br.readLine())) {
    10. sb.append(line);
    11. }
    12. fis.close();
    13. isr.close();
    14. br.close();
    15. Student student = new Student();
    16. //利用JSONObject进行解析
    17. JSONObject stuJsonObject = new JSONObject(sb.toString());
    18. //为什么不用getString?
    19. //optString会在得不到你想要的值时候返回空字符串"",而getString会抛出异常
    20. String name = stuJsonObject.optString("name", "");
    21. student.setName(name);
    22. student.setSax(stuJsonObject.optString("sax", "男"));
    23. student.setAge(stuJsonObject.optInt("age", 18));
    24. //获取数组数据
    25. JSONArray couresJson = stuJsonObject.optJSONArray("courses");
    26. for (int i = 0; i < couresJson.length(); i++) {
    27. JSONObject courseJsonObject = couresJson.getJSONObject(i);
    28. Course course = new Course();
    29. course.setName(courseJsonObject.optString("name", ""));
    30. course.setScore((float) courseJsonObject.optDouble("score", 0));
    31. student.addCourse(course);
    32. }
    33. Log.i(TAG, "parseJson: " + student);
    34. Toast.makeText(context, "解析成功", Toast.LENGTH_LONG).show();
    35. }

    2> Gson 解析

    解析原理:基于事件驱动;

    解析流程:根据所需取的数据 建立1个对应于JSON数据的JavaBean类,即可通过简单操作解析出所需数据;

    Gson 不要求JavaBean类里面的属性一定全部和JSON数据里的所有key相同,可以按需取数据;

    具体实现

    1.创建一个与JSON数据对应的JavaBean类(用作存储需要解析的数据)

    • JSON的大括号对应一个对象

    • 对象里面有key,value

    • JavaBean的类属性名 = key

    • JSON的方括号对应一个数组

    • JavaBean里面对应的也是数组

    • 对象里 可以有值/对象

    • 若对象里面只有值,没有key,则说明是纯数组,对应JavaBean里的数组类型

    • 若对象里面有值和key,则说明是对象数组,对应JavaBean里的内部类

    • 对象嵌套

    • 建立内部类 该内部类对象的名字 = 父对象的key ,类似对象数组

    1. {
    2. "key": "value",
    3. "simpleArray": [1,2,3],
    4. "arrays": [
    5. [{
    6. "arrInnerClsKey": "arrInnerClsValue",
    7. "arrInnerClsKeyNub": 1
    8. }]
    9. ],
    10. "innerclass": {
    11. "name": "zero",
    12. "age": 25,
    13. "sax": "男"
    14. }
    15. }

    3> 转化成JavaBean

    1. public class GsonBean {
    2. private String key;
    3. private int[] simpleArray;
    4. private List<ArrayInnerclass> arrays;
    5. private Innerclass innerclass;
    6. public String getKey() {
    7. return key == null ? "" : key;
    8. }
    9. public void setKey(String key) {
    10. this.key = key;
    11. }
    12. public int[] getSimpleArray() {
    13. return simpleArray;
    14. }
    15. public void setSimpleArray(int[] simpleArray) {
    16. this.simpleArray = simpleArray;
    17. }
    18. public List<ArrayInnerclass> getArrays() {
    19. if (arrays == null) {
    20. return new ArrayList<>();
    21. }
    22. return arrays;
    23. }
    24. public void setArrays(List arrays) {
    25. this.arrays = arrays;
    26. }
    27. public Innerclass getInnerclass() {
    28. return innerclass;
    29. }
    30. public void setInnerclass(Innerclass innerclass) {
    31. this.innerclass = innerclass;
    32. }
    33. private static class Innerclass{
    34. private String name;
    35. private String sax;
    36. private int age;
    37. public String getName() {
    38. return name == null ? "" : name;
    39. }
    40. public void setName(String name) {
    41. this.name = name;
    42. }
    43. public String getSax() {
    44. return sax == null ? "" : sax;
    45. }
    46. public void setSax(String sax) {
    47. this.sax = sax;
    48. }
    49. public int getAge() {
    50. return age;
    51. }
    52. public void setAge(int age) {
    53. this.age = age;
    54. }
    55. }
    56. private static class ArrayInnerclass{
    57. private String arrInnerClsKey;
    58. private int arrInnerClsKeyNub;
    59. public String getArrInnerClsKey() {
    60. return arrInnerClsKey == null ? "" : arrInnerClsKey;
    61. }
    62. public void setArrInnerClsKey(String arrInnerClsKey) {
    63. this.arrInnerClsKey = arrInnerClsKey;
    64. }
    65. public int getArrInnerClsKeyNub() {
    66. return arrInnerClsKeyNub;
    67. }
    68. public void setArrInnerClsKeyNub(int arrInnerClsKeyNub) {
    69. this.arrInnerClsKeyNub = arrInnerClsKeyNub;
    70. }
    71. }
    72. }

    4> Gson原理解析

    在这个序列化和反序列化的过程中, 充当的了一个解析器的角色

    0) 解析过程

    编写一个Json解析器实际上就是一个方法,它的输入是一个表示JSON的字符串,输出是结构化的对应到语言本身的数据结构

    一般来说,解析过程包括 词法分析 和 语法分析两个阶段:

    *1.词法分析

    - BEGIN_OBJECT({)

    - END_OBJECT(})

    - BEGIN_ARRAY([)

    - END_ARRAY(])

    - NULL(null)

    - NUMBER(数字)

    - STRING(字符串)

    - BOOLEAN(true/false)

    - SEP_COLON(:)

    - SEP_COMMA(,)

    *2.语法分析

    n ➔ null

    t ➔ true

    f ➔ false

    " ➔ string

    0-9/- ➔ number

    [ ➔ array

    { ➔ object

    1) JsonElement

    该类是一个抽象类,代表着json串的某一个元素。这个元素可以是一个Json(JsonObject)、可以是一个 数组(JsonArray)、可以是一个Java的基本类型(JsonPrimitive)、当然也可以为 null(JsonNull);JsonObject,JsonArray,JsonPrimitive,JsonNull都是JsonElement这个抽象类的子类。 JsonElement提供了一系列的方法来判断当前的JsonElement 各个JsonElement的关系可以用如下图表示:

    JsonObject对象可以看成 name/values的集合,而这写values就是一个个JsonElement,他们的结构可以

    用如下图表示:

    2) JsonDeserializer原理

    3) TypeAdapter的原理

    JSON适配器模式

    read 将json->bean write 将bean 转为 json

    4) Gson的整体解析原理

    TypeToken :获取gson T 的类型

    5) Gson的反射解析机制

     

    6) Gson解析常见的错误

    Expected BEGIN_ARRAY but was STRING at line 1 column 27

    这种错误一般都是原来是一个字段需要是数组类型,但是事实上给的是””,导致的

    -解决办法

    1. 让返回null即可解决问题

    2. 用Gson自带的解决方案

  • 相关阅读:
    实用的Visual Studio插件
    tictoc例子理解10-13
    opencv中直方图和颜色跟踪相关:calcHist, calcBackProject, Meanshift和Camshift
    EasyExcel的应用
    浏览器中的音视频知识总结v1.0(工作中需要和视频打交道必看!)
    设计模式(一)-设计原则(1)
    代码随想录算法训练营Day36 —— 435. 无重叠区间、763.划分字母区间、56. 合并区间
    Solidity拓展:数学运算过程中数据长度溢出的问题
    哪些场景需要额外注意线程安全问题
    亚马逊云科技与伊克罗德推出AI绘画解决方案——imAgine
  • 原文地址:https://blog.csdn.net/x910131/article/details/126023376