前言:
开发esp32我最喜欢使用的IDF框架,灵活、便捷和全面。此文章使用IDF框架下的espressif__json_generator和espressif__json_parser组件,来分别实现的是JSON数据格式的创建与解析。
一、导入组件
1、espressif__jsmn被依赖,所以也会被自动下载
二、编写解析例程
1、官方没有写好的例子可以跑,所以自己写一个进行全面测试
#define json_test_str \
"{\n\"str_val\" : \"JSON Parser\",\n" \
"\t\"float_val\" : 2.0,\n" \
"\"int_val\" : 2017,\n" \
"\"bool_val\" : false,\n" \
"\"supported_el\" :\t [\"bool\",\"int\"," \
"\"float\",\"str\"" \
",\"object\",\"array\"],\n" \
"\"features\" : { \"objects\":true, " \
"\"arrays\":\"yes\"},\n" \
"\"int_64\":109174583252}"
void parse_json_example(void) {
jparse_ctx_t jctx;
int ret = json_parse_start(&jctx, json_test_str, strlen(json_test_str));
char str_val[64];
int int_val, num_elem;
int64_t int64_val;
bool bool_val;
float float_val;
json_obj_get_string(&jctx, "str_val", str_val, sizeof(str_val));
ESP_LOGI(SYSTEN_TAG, "JSON Parser :%s", str_val);
json_obj_get_float(&jctx, "float_val", &float_val);
ESP_LOGI(SYSTEN_TAG, "float_val :%f", float_val);
json_obj_get_int(&jctx, "int_val", &int_val);
ESP_LOGI(SYSTEN_TAG, "int_val :%d", int_val);
json_obj_get_bool(&jctx, "bool_val", &bool_val);
ESP_LOGI(SYSTEN_TAG, "bool_val :%d", bool_val);
json_obj_get_array(&jctx, "supported_el", &num_elem);
for (int i = 0; i < num_elem; ++i) {
json_arr_get_string(&jctx, i, str_val, sizeof(str_val));
ESP_LOGI(SYSTEN_TAG, "supported_el[%d] :%s", i, str_val);
}
json_obj_leave_array(&jctx);
json_obj_get_object(&jctx, "features");
json_obj_get_bool(&jctx, "objects", &bool_val);
ESP_LOGI(SYSTEN_TAG, "objects :%d", bool_val);
json_obj_get_string(&jctx, "arrays", str_val, sizeof(str_val));
ESP_LOGI(SYSTEN_TAG, "arrays :%s", str_val);
json_obj_leave_object(&jctx);
json_obj_get_int64(&jctx, "int_64", &int64_val);
ESP_LOGI(SYSTEN_TAG, "int64_val :%lld", int64_val);
json_parse_end(&jctx);
}
2、在需要测试地方调用parse_json_example就会将每一项都解析打印
三、编写创建例程
1、官方根本没有例子可以跑,所以自己写一个进行全面测试
// 自定义 flush 回调函数:用于打印或发送数据
void json_flush_callback(const char *buffer, void *priv_data) {
printf("%s\r\n", buffer); // 打印到控制台
}
void generator_json_example(void) {
char buffer[256]; // 用作 JSON 构建缓冲区
json_gen_str_t jstr;
// 初始化 JSON 生成器
json_gen_str_start(&jstr, buffer, 256, json_flush_callback, NULL);
// 开始对象
json_gen_start_object(&jstr);
// 添加键值对
json_gen_obj_set_string(&jstr, "name", "ESP32");
json_gen_obj_set_float(&jstr, "temp", 25.5f);
json_gen_obj_set_bool(&jstr, "online", true);
// 添加数组
json_gen_push_array(&jstr, "sensors");
json_gen_arr_set_int(&jstr, 10);
json_gen_arr_set_int(&jstr, 20);
json_gen_arr_set_int(&jstr, 30);
json_gen_pop_array(&jstr);
// 嵌套对象
json_gen_push_object(&jstr, "location");
json_gen_obj_set_float(&jstr, "lat", 32.021779f);
json_gen_obj_set_float(&jstr, "lon", 118.747673f);
json_gen_pop_object(&jstr);
// 结束对象
json_gen_end_object(&jstr);
// 最后刷新剩余内容
json_gen_str_end(&jstr);
}
2、在需要测试地方调用parse_json_example就会将构建好的json打印出来
3、解答json_gen_end_object(&jstr);函数疑惑
这个函数的用意其实就是创建json数据的最后一步,将数据尾部加一个“}”
4、解答json_gen_str_end(&jstr);函数疑惑
只是为了触发调用回调函数看看前面 构建的正不正确,然后会把构建占用的内存都清空掉的,实际产品使用中,可以不用此函数