一、JSON简介

JSON (JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

1.1 JSON 语法规则

在 JS 语言中,一切都是对象。 因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型:

● 对象表示为键值对
● 数据由逗号分隔
● 花括号保存对象
● 方括号保存数组

1.2 JSON 键/值对

JSON 键值对是用来保存 JS 对象的一种方式,键/值对组合中的键名写在前面并用双引号 “” 包裹,使用冒号 : 分隔,然后紧接着值:

{"firstName": "Json"}

二、添加cJSON

文件位于 esp-idf\components\json\cJSON
使用时包含头文件 cJSON.h

#include "cJSON.h"

三、生成JSON数据

流程:创建JSON结构体 --> 添加数据 --> 释放内存

3.1 创建JSON结构体

cJSON *pRoot = cJSON_CreateObject();                         // 创建JSON根部结构体
cJSON *pValue = cJSON_CreateObject();                        // 创建JSON子叶结构体

3.2 添加字符串类型数据

cJSON_AddStringToObject(pRoot,"mac","65:c6:3a:b2:33:c8");    // 添加字符串类型数据到根部结构体
cJSON_AddItemToObject(pRoot, "value",pValue);
cJSON_AddStringToObject(pValue,"day","Sunday");              // 添加字符串类型数据到子叶结构体

3.3 添加整型数据

cJSON_AddNumberToObject(pRoot,"number",2);                   // 添加整型数据到根部结构体

3.4 添加数组类型数据

3.4.1 整型数组

int hex[5]={51,15,63,22,96};
cJSON *pHex = cJSON_CreateIntArray(hex,5);                   // 创建整型数组类型结构体
cJSON_AddItemToObject(pRoot,"hex",pHex);                     // 添加整型数组到数组类型结构体

3.4.2 JSON对象数组

cJSON * pArray = cJSON_CreateArray();                        // 创建数组类型结构体
cJSON_AddItemToObject(pRoot,"info",pArray);                  // 添加数组到根部结构体
cJSON * pArray_relay = cJSON_CreateObject();                 // 创建JSON子叶结构体
cJSON_AddItemToArray(pArray,pArray_relay);                   // 添加子叶结构体到数组结构体
cJSON_AddStringToObject(pArray_relay, "relay", "on");        // 添加字符串类型数据到子叶结构体

3.5 格式化JSON对象

char *sendData == cJSON_Print(pRoot);                        // 从cJSON对象中获取有格式的JSON对象
os_printf("data:%s\n", sendData);                            // 打印数据

生成JSON格式:

{"mac": "65:c6:3a:b2:33:c8","value": {"day": "Sunday"                },"number": 2,"hex": [51,15,63,22,96],"info": [{"relay": "on"        }]
}

3.6 释放内存

cJSON_free((void *) sendData);                             // 释放cJSON_Print ()分配出来的内存空间
cJSON_Delete(pRoot);                                       // 释放cJSON_CreateObject ()分配出来的内存空间

这里说明一下,我们前面调用了3次cJSON_CreateObject (),最后只需要针对root调用一次释放即可,因为后面创建的对象也是挂接在root上的。

四、解析JSON数据

流程:判断JSON格式 --> 解析数据 --> 释放内存

4.1 判断是否JSON格式

// receiveData是要剖析的数据
//首先整体判断是否为一个json格式的数据
cJSON *pJsonRoot = cJSON_Parse(receiveData);
//如果是否json格式数据
if (pJsonRoot !=NULL)
{···
}

4.2 解析字符串类型数据

char bssid[23] = {0};
cJSON *pMacAdress = cJSON_GetObjectItem(pJsonRoot, "mac");    // 解析mac字段字符串内容
if (!pMacAdress) return;                                      // 判断mac字段是否json格式
else
{if (cJSON_IsString(pMacAdress))                           // 判断mac字段是否string类型{strcpy(bssid, pMacAdress->valuestring);               // 拷贝内容到字符串数组}
}

4.3 解析子叶结构体

char strDay[23] = {0};
cJSON *pValue = cJSON_GetObjectItem(pJsonRoot, "value");      // 解析value字段内容
if (!pValue) return;                                          // 判断value字段是否json格式
else
{cJSON *pDay = cJSON_GetObjectItem(pValue, "day");         // 解析子节点pValue的day字段字符串内容if (!pDay) return;                                        // 判断day字段是否json格式else{if (cJSON_IsString(pDay))                             // 判断day字段是否string类型{strcpy(strDay, pDay->valuestring);                // 拷贝内容到字符串数组}}
}

4.4 解析整型数组数据

cJSON *pArry = cJSON_GetObjectItem(pJsonRoot, "hex");        // 解析hex字段数组内容
if (!pArry) return;                                          // 判断hex字段是否json格式
else
{int arryLength = cJSON_GetArraySize(pArry);              // 获取数组长度int i;for (i = 0; i < arryLength; i++){                                                        // 打印数组内容os_printf("cJSON_GetArrayItem(pArry, %d)= %d\n",i,cJSON_GetArrayItem(pArry, i)->valueint);        }
}

4.5 解析JSON对象数组数据

cJSON *pArryInfo = cJSON_GetObjectItem(pJsonRoot, "info");   // 解析info字段数组内容
cJSON *pInfoItem = NULL;
cJSON *pInfoObj = NULL;
char strRelay[23] = {0};
if (!pArryInfo) return;                                      // 判断info字段是否json格式
else
{int arryLength = cJSON_GetArraySize(pArryInfo);          // 获取数组长度int i;for (i = 0; i < arryLength; i++){pInfoItem = cJSON_GetArrayItem(pArryInfo, i);        // 获取数组中JSON对象if(NULL != pInfoItem){pInfoObj = cJSON_GetObjectItem(pInfoItem,"relay");// 解析relay字段字符串内容   if(pInfoObj){strcpy(strRelay, pInfoObj->valuestring);      // 拷贝内容到字符串数组}}                                                   }
}

解析JSON数据:

{"mac": "65:c6:3a:b2:33:c8","value": {"day": "Sunday"                },"number": 2,"hex": [51,15,63,22,96],"info": [{"relay": "on"        }]
}

4.6 释放内存

cJSON_Delete(pJsonRoot);                                      // 释放cJSON_Parse()分配出来的内存空间

五、常用库函数

  1. 从给定的JSON字符串中得到cJSON对象
    cJSON *cJSON_Parse(const char *value)
  2. 从cJSON对象中获取有格式的JSON对象
    char *cJSON_Print(cJSON *item)
  3. 删除cJSON对象,释放链表占用的内存空间
    void cJSON_Delete(cJSON *c)
  4. 获取cJSON对象数组成员的个数
    int cJSON_GetArraySize(cJSON *array)
  5. 根据下标获取cJSON对象数组中的对象
    cJSON *cJSON_GetArrayItem(cJSON*array,int item)
  6. 根据键获取对应的值(cJSON对象)
    cJSON *cJSON_GetObjectItem(cJSON*object,const char *string)
  7. 新增一个字符串类型字段到JSON格式的数据
    cJSON_AddStringToObject(object,name,s)
  8. 新增一个新的子节点cJSON到根节点
    void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)

• 由 Leung 写于 2021 年 5 月 7 日

• 参考:cJSON的结构与常用函数说明

ESP32学习笔记(12)——JSON接口使用相关推荐

  1. ESP32学习笔记(20)——SPI(从机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

  2. ESP32学习笔记(19)——SPI(主机)接口使用

    一.SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线.它被广泛地使用在 ADC.LCD ...

  3. ESP32学习笔记(7)——SmartConfig接口使用(ESP-Touch和AirKiss)

    一.概述 SmartConfig是TI开发的一种配置技术,用于将新的Wi-Fi设备连接到Wi-Fi网络.它使用移动应用程序将网络凭据从智能手机或平板电脑广播到未配置的Wi-Fi设备. 该技术的优点是设 ...

  4. Kotlin学习笔记12——数据类和密封类

    Kotlin学习笔记12--数据类和密封类 前言 数据类 在类体中声明的属性 复制 componentN 解构声明 密封类 尾巴 前言 上一篇,我们学习了Kotlin中的拓展,今天继续来学习Kotli ...

  5. ESP32学习笔记(49)——RFID RC522使用

    一.简介 MF RC522 是应用于 13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员.是 NXP 公司针对"三表"应用推出的一款低电压.低成本.体积小的非接触式读写 ...

  6. ESP32学习笔记(30)——BLE GATT服务端自定义服务和特征

    一.简介 1.1 低功耗蓝牙(BLE)协议栈 链路层(LL) 控制设备的射频状态,有五个设备状态:待机.广播.扫描.初始化和连接. 广播 为广播数据包,而 扫描 则是监听广播. GAP通信中角色,中心 ...

  7. ESP32学习笔记(1)——搭建环境、编译烧写(Windows+VS Code)

    Espressif-IDE 环境搭建参看 ESP32学习笔记(50)--搭建环境.编译烧写(Windows+Espressif-IDE) 一.搭建环境 1.1 官方资料 ESP-IDF 编程指南 1. ...

  8. ESP32学习笔记(27)——BLE GAP主机端扫描

    一.背景 1.1 低功耗蓝牙(BLE)协议栈 链路层(LL) 控制设备的射频状态,有五个设备状态:待机.广播.扫描.初始化和连接. 广播 为广播数据包,而 扫描 则是监听广播. GAP通信中角色,中心 ...

  9. ESP32学习笔记(七) 复位和时钟

    ESP32学习笔记(七) 复位和时钟 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介绍 ...

  10. ESP32学习笔记(一) 芯片型号介绍

    ESP32学习笔记(一) 芯片型号介绍 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介 ...

最新文章

  1. a和a数值大小 计算机,Java求s=a+aa+aaa+aaaa+aa...a的值
  2. P3966 [TJOI2013]单词
  3. 【youcans 的 OpenCV 例程200篇】152. 边缘检测之 LoG 算子
  4. linux系统启动故障排除
  5. hashmap 允许key重复吗_HashTable和HashMap的区别详解
  6. linux怎么快速输入括弧,中括号怎么打-linux运维:shell脚本中花括号的使用技巧...
  7. 安卓apk的编译与反编译
  8. 3GPP规范命名规则解读
  9. HTML 动画(一)
  10. activiti7基础入门、activiti7实战、activiti7运用
  11. 文献阅读-CSC-中文错别字-有关论文搜集-+CGED
  12. Linux驱动 | DS18B20驱动编程
  13. 51单片机的定时器/计数器及编程
  14. JDK源码解析之HashSet
  15. 微分方程(Differential Equation)
  16. CI/CD---使用新版云效流水线自动部署Java项目
  17. 【HTML+CSS】字体字号行高
  18. 表白,游戏,跨年,各种节日祝福的link
  19. MySQL给表和字段添加注释
  20. android控件显示在最上层,「总是可见的时钟和备忘录」永远显示在屏幕最上层的贴心助手(Android)...

热门文章

  1. Excel 一些数据处理技巧
  2. JPG png GIF BMP常见图像格式的介绍与区别
  3. CentOS修改tomcat端口
  4. linux安装谷歌浏览器(Chrome)
  5. QRCode.js 生成二维码(文字信息二维码)
  6. 图像处理特征提取之(二):Haar特征
  7. ESP32 WS2812B灯带 代码
  8. 阿里面试算法题(一)
  9. 学习如何使用css给数字加圆圈效果
  10. excel中如何对比两个表格的重复数据