目录
JSON介绍
JSON 语法规则
JSON 键/值对
打包解包JSON数据
生成JSON数据
解析JSON数据
使用例子
JSON(JavaScript Object Notation, JS 对象简谱)是一种轻量级的数据交换格式。它就是一种数据格式
在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型:
● 对象表示为键值对
● 数据由逗号分隔
● 花括号保存对象
● 方括号保存数组
JSON 键值对是用来保存 JS 对象的一种方式,键/值对组合中的键名写在前面并用双引号 "" 包裹,使用冒号 : 分隔,然后紧接着值:
{"firstName": "Json"}
JSON 是树状结构,而 JSON 只包含 6 种数据类型:
打包解包JSON数据
流程:创建JSON结构体 --> 添加数据 --> 释放内存
先判断整体是否一个json
格式数据;
然后一层一层来剖析json
格式数据;
有的是json嵌套json。
流程:判断JSON格式 --> 解析数据 --> 释放内存
生成json
格式的方法很多种,觉得最大效率的就是用sprintf()
函数,这个是傻瓜式,直接套模板就行了。
在esp8266中就是使用cjson生成的json数据格式,结果有问题,当处理数据到一定的次数之后就会产生内存不足,重新启动WiFi模块,最后只能使用sprintf产生json数据。
void ICACHE_FLASH_ATTR myparseJson() {
//首先创建一个json数据
/*
{
"myid": "84:f3:eb:b3:a7:05",
"number": 2,
"value": {
"name": "XXX",
"age": 18
},
"hexArry": [51, 15, 63, 22, 96]
}
* */
char * jsonStr = "{ \"myid\": \"84:f3:eb:b3:a7:05\", \"number\": 2,\"value\": {\"name\": \"XXX\",\"age\": 18}, \"hexArry\": [51, 15, 63, 22, 96] }";
//首先整体判断是否为一个json格式的数据
cJSON *pJsonstr = cJSON_Parse(jsonStr);
if (pJsonstr !=NULL) {
//串口打印这段数据
char *s = cJSON_Print(pJsonstr);
os_printf("pJsonstr: %s\r\n", s);
cJSON_free((void *) s);
//------------------------------------------------------
//解析myid字段字符串内容
cJSON *pMyidAdress = cJSON_GetObjectItem(pJsonstr, "myid");
//判断myid字段是否json格式
if (pMyidAdress) {
//判断mac字段是否string类型
if (cJSON_IsString(pMyidAdress))
os_printf("get MyidAdress:%s \n", pMyidAdress->valuestring);
} else
os_printf("get MacAdress failed \n");
//------------------------------------------------------
//解析number字段int内容
cJSON *pNumber = cJSON_GetObjectItem(pJsonstr, "number");
//判断number字段是否存在
if (pNumber){
//判断number字段是否数字整型类型
if (cJSON_IsNumber(pNumber))
os_printf("get Number:%d \n", pNumber->valueint);
}
else
os_printf("get Number failed \n");
//解析value字段内容,判断是否为json
cJSON *pValue = cJSON_GetObjectItem(pJsonstr, "value");
if (pValue) {
//进一步剖析里面的name字段:注意这个根节点是 pValue
cJSON *pName = cJSON_GetObjectItem(pValue, "name");
if (pName)
if (cJSON_IsString(pName))
os_printf("get value->Name : %s \n", pName->valuestring);
//进一步剖析里面的age字段:注意这个根节点是 pValue
cJSON *pAge = cJSON_GetObjectItem(pValue, "age");
if (pAge)
if (cJSON_IsNumber(pAge))
os_printf("get value->Age : %d \n", pAge->valueint);
}
//------------------------------------------------------
//剖析
cJSON *pArry = cJSON_GetObjectItem(pJsonstr, "hexArry");
if (pArry) {
//获取数组长度
int arryLength = cJSON_GetArraySize(pArry);
os_printf("get arryLength : %d \n", arryLength);
//逐个打印
int i ;
for (i = 0; i < arryLength; i++)
os_printf("cJSON_GetArrayItem(pArry, %d)= %d\n",i,cJSON_GetArrayItem(pArry, i)->valueint);
}
} else {
os_printf("this is not a json data ... \n");
}
cJSON_Delete(pJsonstr);
}
void ICACHE_FLASH_ATTR mycreatJson(){
/*
{
"project": {
"mcu": "pro_mrt",
"cpu": "robot"
},
}
*/
//从里向外创建
cJSON *pRoot = cJSON_CreateObject();
cJSON *pRoot1 = cJSON_CreateObject();
cJSON_AddStringToObject(pRoot1,"mcu","pro_mrt");
cJSON_AddStringToObject(pRoot1,"cpu","robot");
cJSON_AddItemToObject(pRoot,"project",pRoot1);
char *s = cJSON_Print(pRoot);
os_printf("\r\n creatJson : %s\r\n", s);
cJSON_free((void *) s);
cJSON_Delete(pRoot);
}
获取版本
cJSON_Version(void);
cJSON_InitHooks(cJSON_Hooks* hooks);
cJSON_Parse(const char *value);
cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
cJSON_Print(const cJSON *item);
cJSON_PrintUnformatted(const cJSON *item);
cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
cJSON_Delete(cJSON *c);
cJSON_GetArraySize(const cJSON *array);
cJSON_GetArrayItem(const cJSON *array, int index);
cJSON_GetObjectItem(const cJSON * const object, const char * const string);
cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
cJSON_HasObjectItem(const cJSON *object, const char *string);
cJSON_GetErrorPtr(void);
cJSON_IsInvalid(const cJSON * const item);
cJSON_IsFalse(const cJSON * const item);
cJSON_IsTrue(const cJSON * const item);
cJSON_IsBool(const cJSON * const item);
cJSON_IsNull(const cJSON * const item);
cJSON_IsNumber(const cJSON * const item);
cJSON_IsString(const cJSON * const item);
cJSON_IsArray(const cJSON * const item);
cJSON_IsObject(const cJSON * const item);
cJSON_IsRaw(const cJSON * const item);
cJSON_CreateNull(void);
cJSON_CreateTrue(void);
cJSON_CreateFalse(void);
cJSON_CreateBool(cJSON_bool boolean);
cJSON_CreateNumber(double num);
cJSON_CreateString(const char *string);
cJSON_CreateRaw(const char *raw);
cJSON_CreateArray(void);
cJSON_CreateObject(void);
cJSON_CreateIntArray(const int *numbers, int count);
cJSON_CreateFloatArray(const float *numbers, int count);
cJSON_CreateDoubleArray(const double *numbers, int count);
cJSON_CreateStringArray(const char **strings, int count);
cJSON_AddItemToArray(cJSON *array, cJSON *item);
cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
cJSON_DetachItemFromArray(cJSON *array, int which);
cJSON_DeleteItemFromArray(cJSON *array, int which);
cJSON_DetachItemFromObject(cJSON *object, const char *string);
cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
cJSON_DeleteItemFromObject(cJSON *object, const char *string);
cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
cJSON_Minify(char *json);
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
(void *) cJSON_malloc(size_t size);
cJSON_free(void *object);
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
1、注意每次使用(包括剖析和生成)之后,都要记得释放内存,就是调用cJSON_Delete()方法,否则一直在占据内存,像8266这样的本身内存就少,运行久了就会死机的 !
2、在剖析数据时候,一定要遵循规范,一定要判断是否json数据,而且是否想要的类型,比如字符串,整型,这些都是要认真核对。否则会造成esp8266重启。
3、在处理数组时候,一定要注意不要数组越界问题!