JSON数据格式讲解与cJSON库的使用

news2024/11/27 8:06:11

文章目录

  • 写在前面
  • 一、安装cJSON
  • 二、使用cJSON
    • 1、使用的文件
    • 2、如何传输数据:****
  • 三、JSON语法
  • 四、cJSON函数讲解
    • 1、cJSON结构体 **
    • 2、cJSON结构体与字符串之间的转换(重要)
      • 2.1、标题将cJSON结构体转换为字符串(常用)
      • 2.2、将字符串转为cJSON结构体(常用)
    • 3、cJSON创建键值对
      • 3.1、先调用 cJSON_CreateXXX 创建对象或数组,然后调用 cJSON_AddItemToObject 将值加入到对象或数组中
      • 3.2、直接调用 cJSON_AddXXXToObject 创建并添加值到对象中
    • 4、解析
    • 5、释放cJSON数据
  • 五、示例
    • 1、创建
    • 2、解析(主要参考与使用)
      • 2.1、解析 {}
      • 2.2、解析[ {} {} ]
    • 3、解析(参考形式)
      • 3.1、解析 {}
      • 3.2、解析 [ ]
      • 3.3、解析 [ {} {} ]
      • 3.4、解析[ [ ] [ ] ]
      • 3.5、解析 { { } { } }
    • 参考文章

写在前面

什么是JSON:一种轻量级的数据交换格式
JSON用途:解析收到的数据和发送对方能够解析的数据
什么是cJSON:c语言格式下使用JSON的工具

一、安装cJSON

cjson官方库,直接点击下载zip,解压缩

git clone https://github.com/DaveGamble/cJSON.git
cd cJSON/
mkdir build
cd build/
cmake ..
make
make install

二、使用cJSON

1、使用的文件

然后我们,可以看到很多文件,但是,我们不需要这么多,使用cjson只需要两个文件,
拷贝cJSON.c和cJSON.h文件到自己的项目中就可以了,linux,windows上都可以使用

CJOSN.h
CJSON.c

2、如何传输数据:****

1、创建cJSON格式数据,转换成为cJSON字符串,然后传输。
2、将cJSON字符串解析成cJSON格式数据,然后提取出相应的数据内容。

三、JSON语法

JSON对象是一个无序的"key(关键字)/value(值)"键值对的集合:
"{“开始,以”}“结束 ,允许嵌套使用
每个key(关键字)和value(值)成对出现,关键字和值之间使用”:“分隔
键/值之间用”,"分隔
在这些字符前后允许存在无意义的空白符

其中**关键字**
			只能是字符串(使用双引号“”表示)


****可以有如下表示:
					数字(整数或浮点数)
					字符串(在双引号中)
					逻辑值(true 或 false)
					数组 (在中括号中)
					对象 (在大括号中)
					null

四、cJSON函数讲解

1、cJSON结构体 **

/* The cJSON structure: */
typedef struct cJSON
{
//这些不用管
    struct cJSON *next;
    struct cJSON *prev;
    struct cJSON *child;

//这些都要知道
    //该json对象的类型,可以是字符串,int,double....
    int type;
    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    //如果类型是字符串,那么键值的字符串的值存在这里
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
     //如果类型是int,那么值存在这里
    int valueint;
    /* The item's number, if type==cJSON_Number */
    //如果类型是double,那么值存在这里
    double valuedouble;
    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
  	//存放名字的地方
    char *string;
} cJSON;

2、cJSON结构体与字符串之间的转换(重要)

2.1、标题将cJSON结构体转换为字符串(常用)

使用这个两个函数一定一定一定要 调用cJSON_Delete函数 释放它们返回的指针内存

//将CJSON数据转换为字符串(保留原来的格式:例如会保留空格和回车)
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
//将CJSON数据转换为字符串(删除所有格式,只保留文本)
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);

2.2、将字符串转为cJSON结构体(常用)

//将json字符串转换为结构体,并且将其赋给一个指针
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);

3、cJSON创建键值对

3.1、先调用 cJSON_CreateXXX 创建对象或数组,然后调用 cJSON_AddItemToObject 将值加入到对象或数组中

CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);	//创建对象---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);	//创建数组---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);//创建整型数组
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);//创建双浮点型数组

CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);	//在对象中添加项目
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);//在数组中添加项目

3.2、直接调用 cJSON_AddXXXToObject 创建并添加值到对象中

CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);

4、解析

注意:解析—是从cJSON结构体类型中—解析

//获取数组大小
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
//获取数组里面的某一个值
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
//这个函数将某一个键值对,提取出来放到一个结构体中
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)

5、释放cJSON数据

void  cJSON_Delete(cJSON *c);
/*作用:释放位于堆中cJSON结构体内存

五、示例

1、创建

#include <stdio.h>
#include "cJSON.h"

int main(void)
{
	double  grade[4]={66.51,118.52,61.53,128.54};
	int		time[4]={123,456,789,150};
	
	cJSON *TCP = cJSON_CreateObject();				//创建一个对象
	
 	cJSON_AddStringToObject(TCP,"name","MQ");		//添加字符串 
	cJSON_AddNumberToObject(TCP,"age",25);	    	//添加整型数字 
	cJSON_AddNumberToObject(TCP,"height",183.52);	//添加浮点型数字
	cJSON_AddFalseToObject(TCP,"gender");			//添加逻辑值false
	 
	cJSON *ADD	= cJSON_CreateObject();				//创建一个对象
	cJSON_AddStringToObject(ADD,"country","China");	//添加字符串 
	cJSON_AddNumberToObject(ADD,"zip-code",123456);	//添加整型数字
	cJSON_AddItemToObject(TCP,"address",ADD);
 	
	cJSON *SUB  = cJSON_CreateArray();				//创建一个数组
	cJSON_AddStringToObject(SUB,"","政治"); 		//添加字符串到数组
 	cJSON_AddStringToObject(SUB,"","数学");
	cJSON_AddStringToObject(SUB,"","英语");
	cJSON_AddStringToObject(SUB,"","专业课");
	cJSON_AddItemToObject(TCP,"subject",SUB);		//添加数组到对象
	
	cJSON *TIM  = cJSON_CreateIntArray(time,4);		//创建一个整型数组
	cJSON_AddItemToObject(TCP,"time",TIM);
	
	cJSON *GRA  = cJSON_CreateDoubleArray(grade,4);	//创建一个双浮点型数组
	cJSON_AddItemToObject(TCP,"grade",GRA);
	
	cJSON *STU  = cJSON_CreateArray();			//创建一个数组
	
	cJSON *Z3  = cJSON_CreateObject();			//创建一个对象
	cJSON_AddStringToObject(Z3,"name","张三");	//添加字符串 
	cJSON_AddNumberToObject(Z3,"age",24);	    //添加整型数字 
	cJSON_AddTrueToObject(Z3,"gender");			//添加逻辑值 
	cJSON_AddItemToArray(STU,Z3);				//添加对象到数组中 
	
	cJSON *L4  = cJSON_CreateObject();			//创建一个对象
	cJSON_AddStringToObject(L4,"name","李四");	//添加字符串 
	cJSON_AddNumberToObject(L4,"age",25);	    //添加整型数字 
	cJSON_AddTrueToObject(L4,"gender");			//添加逻辑值 
	cJSON_AddItemToArray(STU,L4);				//添加对象到数组中
	
	cJSON *W5  = cJSON_CreateObject();			//创建一个对象
	cJSON_AddStringToObject(W5,"name","王五");	//添加字符串 
	cJSON_AddNumberToObject(W5,"age",26);	    //添加整型数字 
	cJSON_AddTrueToObject(W5,"gender");			//添加逻辑值 
	cJSON_AddItemToArray(STU,W5);				//添加对象到数组中
	
	cJSON_AddItemToObject(TCP,"student",STU);	//添加数组到对象中

	char *json_data = cJSON_Print(TCP);	//JSON数据结构转换为JSON字符串
	printf("%s\n",json_data);//输出字符串
	cJSON_Delete(TCP);//清除结构体
	return 0;
}

现象

{
	"name":	"MQ",
	"age":	25,
	"height":	183.52,
	"gender":	false,
	"address":	{
		"country":	"China",
		"zip-code":	123456
	},
	"subject":	["政治", "数学", "英语", "专业课"],
	"time":	[123, 456, 789, 150],
	"grade":	[66.51, 118.52, 61.53, 128.54],
	"student":	[{
			"name":	"张三",
			"age":	24,
			"gender":	true
		}, {
			"name":	"李四",
			"age":	25,
			"gender":	true
		}, {
			"name":	"王五",
			"age":	26,
			"gender":	true
		}]
}

2、解析(主要参考与使用)

2.1、解析 {}

int parsecjson_data(char *jsonstring)
{	
	cJSON *cjson= cJSON_Parse(jsonstring);
	if(cjson) 
	{
		//解析 JSON 数据并处理
		cJSON *state = cJSON_GetObjectItem(cjson, "state");
		if (state != NULL && cJSON_IsString(state)) {
			printf("State: %s\n", state->valuestring);		//字符串
		}

		cJSON *brightness = cJSON_GetObjectItem(cjson, "brightness");
		if (brightness != NULL && cJSON_IsNumber(brightness)) {
			printf("Brightness: %d\n", brightness->valueint);		//整形
		}
		
		cJSON *height = cJSON_GetObjectItem(object2, "height");  
		if (height != NULL && cJSON_IsNumber(height)) {
			printf("height: %d \n", height->valuedouble);			//浮点型
		}
		
		cJSON *gender = cJSON_GetObjectItem(object2, "gender");  
		if (gender != NULL && cJSON_IsBool(gender)) {
			printf("gender: %d \n", gender->type);			//布尔类型	true/false
		}
	}
	cJSON_Delete(cjson);
	return 0;
}

2.2、解析[ {} {} ]

int parsecjson_data(char *jsonstring)
{	
	cJSON *cjson = cJSON_Parse(jsonstring);
	
	if (cjson != NULL && cJSON_IsArray(cjson)) {
		
			int array_size = cJSON_GetArraySize(cjson);
			if (array_size >= 2) {
				cJSON *object1 = cJSON_GetArrayItem(cjson, 0);  // 获取数组中的第一个对象
				cJSON *object2 = cJSON_GetArrayItem(cjson, 1);  // 获取数组中的第二个对象
				
				if (object1 != NULL && cJSON_IsObject(object1)) {		// 第一个对象中的字段
				
					cJSON *sens1 = cJSON_GetObjectItem(object2, "K3");  // 第一个对象中有名为 K3 的字段
					if (sens1 != NULL && cJSON_IsNumber(sens1)) {
						car.sens1 = sens1->valueint;
						printf("sens1: %d \n", sens1->valueint);
					}
				} 
				
				if (object2 != NULL && cJSON_IsObject(object2)) {
					
					cJSON *sens2 = cJSON_GetObjectItem(object2, "K4");  // 第二个对象中有名为 K4 的字段
					if (sens2 != NULL && cJSON_IsNumber(sens2)) {
						car.sens2 = sens2->valueint;
						printf("sens2: %d\n", sens2->valueint);
					}
				}
			}
		}
	cJSON_Delete(cjson);
	return 0;
}

3、解析(参考形式)

注释:借鉴参考文章

3.1、解析 {}

1

{
	/*************** 方式一 ***************/
	item = cJSON_GetObjectItem(root, "interest");		// 获取object对象名
	if (item != NULL) {
		cJSON *val = NULL;

		val = cJSON_GetObjectItem(item, "basketball");	// 根据object对象名获得里面的basketball数据
		if (val != NULL && val->type == cJSON_String) {
			v_str = val->valuestring;
			printf("basketball = %s\n", v_str);
		}

		val = cJSON_GetObjectItem(item, "badminton");	// 根据object对象名获得里面的badminton数据
		if (val != NULL && val->type == cJSON_String) {
			v_str = val->valuestring;
			printf("badminton = %s\n", v_str);
		}
	}

	/*************** 方式二 ***************/
	item = cJSON_GetObjectItem(root, "interest");
	if (item != NULL) {
		cJSON *obj = item->child;	// 获得 "basketball":	"篮球"

		while (obj) {
			if (obj->type == cJSON_String) {
				char *v_str = obj->valuestring;
				printf("%s = %s\n", obj->string, v_str);	// 可以通过string获得键
			}
			// 获取下一个元素
			obj = obj->next;
		}
	}
}

3.2、解析 [ ]

2

{
	/*************** 方式一 ***************/
	item = cJSON_GetObjectItem(root, "color");
	if (item != NULL) {
		int size = cJSON_GetArraySize(item);	// 获得数组个数

		for (int i = 0; i < size; i++) {
			cJSON *arr = cJSON_GetArrayItem(item, i);	// 根据索引获得数组中的值

			if (arr != NULL && arr->type == cJSON_String) {
				v_str = arr->valuestring;
				printf("color = %s\n", v_str);
			}
		}
	}


	/*************** 方式二 ***************/
	item = cJSON_GetObjectItem(root, "color");
	if (item != NULL) {
		cJSON *arr = item->child;	// 获得 "black"

		while (arr) {
			if (arr->type == cJSON_String) {
				char *v_str = arr->valuestring;
				printf("color = %s\n", v_str);
			}
			// 获取下一个元素
			arr = arr->next;
		}
	}
}

3.3、解析 [ {} {} ]

3

{
	/*************** 方式一 ***************/
	item = cJSON_GetObjectItem(root, "like");
	if (item != NULL) {
		int size = cJSON_GetArraySize(item);	// 获取的数组大小

		for (int i = 0; i < size; i++) {
			cJSON *obj = cJSON_GetArrayItem(item, i);		// 获取的数组里的obj
			cJSON *val = NULL;

			if (obj != NULL && obj->type == cJSON_Object) {	// 判断数字内的元素是不是obj类型
				val = cJSON_GetObjectItem(obj, "game");		// 获得obj里的值

				if (val != NULL && val->type == cJSON_String) {
					v_str = val->valuestring;
					printf("game = %s\n", v_str);
				}

				val = cJSON_GetObjectItem(obj, "price");
				if (val != NULL && val->type == cJSON_Number) {
					v_double = val->valuedouble;
					printf("price = %.2f\n", v_double);
				}
			}
		}
	}


	/*************** 方式二 ***************/
	item = cJSON_GetObjectItem(root, "like");
	if (item != NULL) {
		cJSON *obj = item->child;	// 获得 { "game": "马里奥", "price": 66.6 }

		while (obj) {
			if (obj->type == cJSON_Object) {

				cJSON *objValue = obj->child;	// 获得 "game": "马里奥"
				while (objValue) {

					// 再通过类型去区分
					if (objValue->type == cJSON_String) {
						char *v_str = objValue->valuestring;
						printf("%s = %s\n", objValue->string, v_str);

					} else if (objValue->type == cJSON_Number) {
						double v_double = objValue->valuedouble;
						printf("%s = %.2f\n", objValue->string, v_double);
					}
					// 获取下一个元素
					objValue = objValue->next;
				}
			}
			// 获取下一组元素
			obj = obj->next;
		}
	}
}

3.4、解析[ [ ] [ ] ]

4

{
	/*************** 方式一 ***************/
	item = cJSON_GetObjectItem(root, "education");
	if (item != NULL) {
		int size = cJSON_GetArraySize(item);	// 获取的数组大小

		for (int i = 0; i < size; i++) {
			cJSON *arr = cJSON_GetArrayItem(item, i);		// 解析获得	[ "小学", "初中" ]

			if (arr != NULL && arr->type == cJSON_Array) {
				int arrSize = cJSON_GetArraySize(arr);

				for (int j = 0; j < arrSize; j++) {
					cJSON *arr2 = cJSON_GetArrayItem(arr, j);	// 再进一步解析就可以得到数组里面的元素了

					if (arr2 != NULL && arr2->type == cJSON_String) {
						v_str = arr2->valuestring;
						printf("education = %s\n", v_str);
					}
				}
			}
		}
	}

	/*************** 方式二 ***************/
	item = cJSON_GetObjectItem(root, "education");
	if (item != NULL) {
		cJSON *arr = item->child;	// 获得 [ "小学", "初中" ]

		while (arr) {
			if (arr->type == cJSON_Array) {
			
				cJSON *arrValue = arr->child;	// 获得 "小学"
				while (arrValue) {
					if (arrValue->type == cJSON_String) {
						char *v_str = arrValue->valuestring;
						printf("education = %s\n", v_str);
					}
					arrValue = arrValue->next;	// 获取下一个元素
				}
			}
			// 获取下一组
			arr = arr->next;
		}
	}
}

3.5、解析 { { } { } }

5

{
	/*************** 方式一 ***************/
	char *arrStr[] = { "serialOne", "serialTwo" };		// 可以提前定义需要解析的对象键,这样就可以使用for循环进行解析了

	item = cJSON_GetObjectItem(root, "languages");
	if (item != NULL) {
		cJSON *val = NULL;
		int size = sizeof(arrStr) / sizeof(char *);

		// 通过遍历指针数组,获得每个对象的键,在进行解析操作(如果不使用for循环解析,那就老老实实的写代码将全部个数解析完毕)
		for (int i = 0; i < size; i++) {
			cJSON *obj1 = cJSON_GetObjectItem(item, arrStr[i]);

			if (obj1 != NULL && obj1->type == cJSON_Object) {

				val = cJSON_GetObjectItem(obj1, "language");
				if (val != NULL && val->type == cJSON_String) {
					v_str = val->valuestring;
					printf("education = %s\n", v_str);
				}

				val = cJSON_GetObjectItem(obj1, "grade");
				if (val != NULL && val->type == cJSON_Number) {
					v_int = val->valueint;
					printf("grade = %d\n", v_int);
				}
			}
		}
	}



	/*************** 方式二 ***************/
	// 在不知道键是什么的情况下 和 不知道有多少元素的情况下可用
	item = cJSON_GetObjectItem(root, "languages");
	if (item != NULL) {
		// 获取到languages里的第一个子元素
		cJSON *obj = item->child;	// 也就是:"serialOne": { "language": "汉语", "grade": 10 }

		while (obj) {
			if (obj->type == cJSON_Object) {

				// 获取到子元素的子元素
				cJSON *value = obj->child;	// 也就是:{ "language": "汉语", "grade": 10 }

				while (value) {
					if (value->type == cJSON_String) {
						printf("%s = %s\n", value->string, value->valuestring);

					} else if (value->type == cJSON_Number) {
						printf("%s = %d\n", value->string, value->valueint);
					}
					// 通过next可以自由获取里面的元素了
					value = value->next;
				}
			}

			// 获得下一组子元素
			obj = obj->next;
		}
	}
}

参考文章

cJSON库用法详解
Cjson入门快速使用
使用cjson库 操作Json格式文件(创建、插入、解析、修改、删除)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1601063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式—门面模式

定义: 门面模式,也称为外观模式&#xff0c;是一种结构型设计模式。它的主要目的是提供统一的接口来访问子系统中的多个接口&#xff0c;从而简化客户端与复杂子系统之间的交互。 在门面模式中&#xff0c;一个门面类充当中介&#xff0c;为客户端提供一个简化了的访问方式&…

B203-若依框架应用

目录 简介版本RuoYi-fast项目准备新增模块/代码生成 简介 基于SpringBoot的权限管理系统&#xff0c;基于SpringBoot开发的轻量级Java快速开发框架 版本 前后端未分离单应用版本&#xff1a;RuoYi-fast&#xff0c;前后端未分离多模块版本&#xff1a;RuoYi 前后端分离单应用…

Adobe AE(After Effects)2020下载地址及安装教程

Adobe After Effects是一款专业级别的视觉效果和动态图形处理软件&#xff0c;由Adobe Systems开发。它被广泛用于电影、电视节目、广告和其他多媒体项目的制作。 After Effects提供了强大的合成和特效功能&#xff0c;可以让用户创建出令人惊艳的动态图形和视觉效果。用户可以…

逻辑回归模型-逻辑回归算法原理-逻辑回归代码与实现-笔记整合

通过一段时间的学习&#xff0c;总算把逻辑回归模型弄清楚了 《老饼讲解-机器学习》www.bbbdata.com中是讲得最清晰的&#xff0c;结合其它资料&#xff0c;整理一个完整的笔记如下&#xff0c;希望能帮助像我这样入门的新人&#xff0c;快速理解逻辑回归算法原理和逻辑回归实…

代码随想录训练营Day 24|Python|Leetcode|93.复原IP地址, 78.子集,90.子集II

93.复原IP地址 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址&#xff0c;但是 &q…

git clone遇到报错“SSL certificate problem: self signed certificate”

在git clone的时候发现遇到了一个问题&#xff1a; cristDESKTOP-JKRNKSH MINGW64 ~/Desktop $ git clone -b dev https://xxx.xxx.xxx.xxx:3001/crist/AVM_V9M.git Cloning into AVM_V9M... fatal: unable to access https://xxx.xxx.xxx.xxx3001/crist/AVM_V9M.git/: SSL ce…

openGauss学习笔记-264 openGauss性能调优-TPCC性能调优测试指导-BIOS配置

文章目录 openGauss学习笔记-264 openGauss性能调优-TPCC性能调优测试指导-BIOS配置264.1 恢复BIOS出厂设置264.2 修改相关BIOS设置264.3 重启操作系统 openGauss学习笔记-264 openGauss性能调优-TPCC性能调优测试指导-BIOS配置 本章节主要介绍openGauss数据库内核基于鲲鹏服务…

自己的事情自己做:使用 Python Turtle 绘制 Python Logo

以下代码中&#xff0c;将向你展示一个有趣的程序&#xff0c;如何使用 Python Turtle 中绘制 Python Logo。Python 翻译成汉语是蟒蛇的意思&#xff0c;Python 的 Logo 也是两条缠绕在一起的蟒蛇。 import turtlepen turtle.Turtle() turtle.bgcolor("black") pe…

Spring基础篇-快速面试笔记(速成版)

文章目录 1. Spring概述2. 控制反转&#xff08;IoC&#xff09;2.1 Spring声明Bean对象的方式2.2 Spring的Bean容器&#xff1a;BeanFactory2.3 Spring的Bean生命周期2.4 Spring的Bean的注入方式 3. Spring的事件监听器&#xff08;Event Listener&#xff09;3.1 Spring内置事…

开源项目|使用go语言搭建高效的环信 IM Rest接口(附源码)

项目背景 环信 Server SDK 是对环信 IM REST API 的封装&#xff0c; 可以节省服务器端开发者对接环信 API 的时间&#xff0c;只需要配置自己的 App Key 相关信息即可使用。 环信目前提供java和PHP版本的Server SDK&#xff0c;此项目使用go语言对环信 IM REST API 进行封装…

stm32实现hid鼠标

启动CubelMX 选择芯片&#xff08;直接输入stm32f103zet6) 设置时钟 如下图 usb设置 配置usb设备 调试端口设置 配置时钟 项目输出设置 打开工程&#xff08;后记&#xff1a;此工程含有中文不能编译通过) 配置项目 配置调试器 编译无法通过 删除路径中的中文&#xff0c;以及…

facenet人脸检测+人脸识别+性别识别+表情识别+年龄识别的C++部署

文章目录 一. 人脸检测二.人脸识别facenet2.1 训练人脸识别模型2.2 导出ONNX2.3 测试 三.人脸属性&#xff08;性别、年龄、表情、是否戴口罩&#xff09;3.1 训练3.2 导出ONNX3.3 测试 四. 集成应用五、Jetson 部署5.1 NX5.2 NANO 一. 人脸检测 代码位置&#xff1a;1.detect …

Java代码执行顺序

Java代码的执行顺序 后面大量的涉及到了static&#xff0c;我曾经写过一篇static的博客&#xff0c;可以看一眼 我上次写了static的加载顺序&#xff0c;没看过的可以进去看一眼 JavaSE&#xff1a;static关键字详解 ---------------------分割线-------------------------…

✌粤嵌—2024/4/3—合并K个升序链表

代码实现&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* merge(struct ListNode *l1, struct ListNode *l2) {if (l1 NULL) {return l2;}if (l2 NULL) {return l1;}struct Lis…

安装指定版本的ant-design-vue和指定版本的@ant-design/icons-vue 图标组件包

前言&#xff1a; 最近在完成公司的项目时&#xff0c;为了兼容其他的版本&#xff0c;需要安装指定版本的ant-design-vue和ant-design/icons-vue 图标组件包&#xff0c;安装成功之后&#xff0c;分享如下&#xff1a; 安装命令&#xff1a; ant-design-vue&#xff1a; 不…

[移动通讯]【无线感知-P1】[从菲涅尔区模型到CSI模型-2]

前言&#xff1a; 前面我们学习了&#xff1a; 1 只 基于机器学习做无线感知问题&#xff1a;泛化性能差&#xff0c;可解释性差 无法解释为什么能做好,什么时候能做好,什么时候做不好. 可行性 到 可用性&#xff0c;泛化性问题&#xff0c;具体深入的研究。 2 无线感知的理论…

解决npm run dev跑项目,发现node版本不匹配,怎么跑起来?【已解决】

首先问题点就是我们npm run dev 运行项目的时候发现出错&#xff0c;跑不起来&#xff0c;类型下面这种 这里的出错的原因在于我们的node版本跟项目的版本不匹配 解决办法 我这里的问题是我的版本是node14的&#xff0c;然后项目需要node20的&#xff0c;执行下面的就可以正…

【面试八股总结】排序算法(二)

参考资料 &#xff1a;阿秀 一、堆排序 堆排序基本思想是先把数组构造成一个大顶堆(父亲节点大于其子节点)&#xff0c;然后把堆顶(数组最大值&#xff0c;数组第一个元素)和数组最后一个元素交换&#xff0c;这样就把最大值放到了数组最后边。把数组长度n-1,再进行构造堆把剩…

HackMyVM-Connection

目录 信息收集 arp nmap WEB web信息收集 dirsearch smbclient put shell 提权 系统信息收集 suid gdb提权 信息收集 arp ┌─[rootparrot]─[~/HackMyVM] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168.9.115 S…

【PostgreSQL里insert on conflict do操作时的冲突报错分析】

最近在巡检PostgreSQL的数据库的时候&#xff0c;发现部分数据库里存在大量的如下报错 ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time HINT: Ensure that no rows proposed for insertion within the same command have duplicate constrained val…