@requestbody 对象接收不到json_例说嵌入式实用知识之JSON数据

这篇博客介绍了在嵌入式开发中如何使用cJSON库进行JSON数据的组包和解析。通过实例展示了如何确定协议数据、组合JSON数据包并提供相关代码示例,同时解释了cJSON库的关键接口及其用途。
摘要由CSDN通过智能技术生成

前言

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。JSON在互联网相关开发中用得很多,在我们嵌入式中用得也不少。最近在项目中就有用到,用起来很方便。

简单的JSON格式数据如:

{    "name": "xxx",    "num": xxx,    "c_score": xxx}

这里我们需要知道一个概念:键值对。比如:

"name": "xxx"

像这样子的就是一对键值对。

当我们作为发送方时,我们要把xxx这些有用的数据组合成JSON格式的数据发送给接收方;当我们作为接收方时,我们需要从这一堆JSON数据中解析出xxx这些有用的数据拿来使用。简单的JSON数据,我们使用C语言的一些字符串操作相关的库函数也是可以做到组包和解析的,但是一些稍微复杂一点的JSON,可能就没那么好操作了。

这时候我们可以借助一个第三方库——cJSON库,可以很方便来做数据组包及解析。

cJSON库仓库地址:

https://github.com/DaveGamble/cJSON.git

或者

https://gitee.com/mirrors/cJSON.git

下面我们通过实例来分享使用cJSON库来做数据组包及数据解析。

组包、解析示例

1、确定协议数据

在实际开发中,要把JSON数据作为通信的数据,自然要先确定通信双方要交互的数据有哪些,如有需要还需编写形成协议文档。协议文档包含要传输的数据,数据类型等信息。比如:

0eb6915d308f5bb405b9425cf9e54f4f.png

2、组JSON数据包示例

从控制台输入一些学生信息,组合成字符串格式的JSON数据包,然后再输出至控制台。

操作示例:

e745969634896087bc94198a0b8fa2fe.png

首先,我们先从仓库下载cJSON源码,文件夹内容如:

a5256c3e23ca5f32ff8952ea4fa23f8f.png

我们只需要把cJSON.c、cJSON.h两个文件复制到我们工程的根目录下就可以使用,如:

a924f04a191ad795766efc6ffbf58c49.png

从cJSON.h可以看到其给我们提供了很多接口:

0c2d5881882f10a7755431086efd98e1.png

本例中我们重点关注如下几个接口即可:

cJSON_CreateObject:创建JSON对象,{}扩起来的cJSON_CreateString:创建字符串cJSON_CreateNumber:创建int类型数据cJSON_AddItemToObject:添加到JSON对象中cJSON_Print:呈现为标准的JSON格式cJSON_PrintUnformatted:呈现为去掉空格的JSON格式cJSON_Delete:JSON对象删除,做一些释放内存的工作

我们创建的的组包函数如下:

static char *StudentsData_Packet(pStudentDef _Stu){    char *res_string = NULL;    // 返回值    cJSON *name = NULL;         // 名字    cJSON *num = NULL;          // 学号    cJSON *c_score = NULL;      // C语言分数    /* 创建一个JSON对象,{}扩起来 */    cJSON *obj = cJSON_CreateObject();    if (obj == NULL)    {        goto end;    }    /* 创建 "name": "xxx" 键值对 */    name = cJSON_CreateString(_Stu->name);    if (name == NULL)    {        goto end;    }    cJSON_AddItemToObject(obj, "name", name);    /* 创建 "num": 207 键值对 */    num = cJSON_CreateNumber(_Stu->num);    if (name == NULL)    {        goto end;    }    cJSON_AddItemToObject(obj, "num", num);        /* 创建 "c_score": 95 键值对 */    c_score = cJSON_CreateNumber(_Stu->c_score);    if (name == NULL)    {        goto end;    }    cJSON_AddItemToObject(obj, "c_score", c_score);     res_string = cJSON_Print(obj);          // 呈现为JSON格式     // res_string = cJSON_PrintUnformatted(obj);   // 呈现为无格式    if (res_string == NULL)    {        fprintf(stderr, "Failed to print monitor.");    }/* 异常情况统一Delete(free) */end:    cJSON_Delete(obj);    return res_string;}

详细解释见注释。我们重点看一下cJSON_Print与cJSON_PrintUnformatted这两个接口。这两个接口的差别就是组合成的JSON数据是否有空格。我们通过JSON相关的在线网站看一下其区别:

https://www.sojson.com/json/json_online.html

有空格的JSON数据,即用cJSON_Print时的效果为:

bdf3876111b8bd9516c1ce2169ae9d32.png

无空格的JSON数据,即用cJSON_PrintUnformatted时的效果为:

76c98cf280f68374831c48040698535d.png

如果想要输出查看时,当然是用cJSON_Print比较方便查看;如果是实际通信时,当然是用cJSON_PrintUnformatted会比较好,毕竟去掉空格就可以减小一定程度的通信负担。

完整代码:

/*    作者:ZhengN    公众号:嵌入式大杂烩*/#include #include #include #include "cJSON.h"#define  STU_NAME_LEN  32/* 学生结构体 */typedef struct _Student{    char name[STU_NAME_LEN];  // 名字          int num;                  // 学号          int c_score;              // C语言分数}StudentDef, *pStudentDef;/* 内部函数声明 */static char *StudentsData_Packet(pStudentDef _Stu);/********************************************************************************************************** 函数: main**------------------------------------------------------------------------------------------------------** 参数: ** 说明: ** 返回: ********************************************
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值