You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ArduinoJson 6创建含4个对象的JSON数组?无需降级

ArduinoJson 6 创建含多个对象的JSON数组问题

我尝试用ArduinoJson 6生成一个包含4个同结构对象的JSON数据,但一直失败。ArduinoJson 5的.createObject方法用起来更顺手,想知道v6为啥移除了这个方法,有没有替代实现,是不是必须降级到v5?

预期生成的JSON格式

{
   "Spot":[
      {
         "LocationId":"673d855c-9f66-4e49-8b2c-737e829d880c",
         "SpotId":"1",
         "Occupied":"Empty"
      },
      {
         "LocationId":"673d855c-9f66-4e49-8b2c-737e829d880c",
         "SpotId":"2",
         "Occupied":"Empty"
      },
      {
         "LocationId":"673d855c-9f66-4e49-8b2c-737e829d880c",
         "SpotId":"3",
         "Occupied":"Empty"
      },
      {
         "LocationId":"673d855c-9f66-4e49-8b2c-737e829d880c",
         "SpotId":"4",
         "Occupied":"Empty"
      }
   ]
}

当前代码

char json_string[256];
StaticJsonDocument<256> carparkResponse;

JsonObject spot1 = carparkResponse.createNestedObject("Spot");
spot1["LocationId"] = LOCATION_ID;
spot1["SpotId"] = "1";
spot1["Occupied"] = occupied1.isOccupied();

JsonObject spot2 = spot1.createNestedObject();
spot2["LocationId"] = LOCATION_ID;
spot2["SpotId"] = "2";
spot2["Occupied"] = occupied2.isOccupied();

JsonObject spot3 = spot2.createNestedObject();
spot3["LocationId"] = LOCATION_ID;
spot3["SpotId"] = "3";
spot3["Occupied"] = occupied3.isOccupied();

JsonObject spot4 = spot3.createNestedObject();
spot4["LocationId"] = LOCATION_ID;
spot4["SpotId"] = "4";
spot4["Occupied"] = occupied4.isOccupied();

serializeJson(carparkResponse, json_string);
Serial.println(json_string);

问题分析与解决方案

1. 当前代码的核心问题

你错误地将Spot创建成了嵌套对象,而非目标格式的JSON数组。createNestedObject("Spot")会在根文档生成一个名为Spot的对象,后续调用createNestedObject()又会在这个对象里嵌套子对象,最终得到的是多层嵌套结构,完全不符合预期的数组格式。

2. ArduinoJson 6 移除.createObject的原因

v6移除该方法是为了简化API、降低内存开销并减少逻辑错误。v5的.createObject需要手动管理对象归属,容易出现内存泄漏或结构混乱;v6通过JsonDocument统一管理所有节点内存,改用createNestedObject()(创建嵌套对象)和createNestedArray()(创建嵌套数组)明确区分结构类型,逻辑更清晰,性能更优。

3. ArduinoJson 6 的正确实现方式

要生成预期格式,需先创建Spot数组,再往数组中逐个添加对象:

改进后的代码

char json_string[256];
StaticJsonDocument<256> carparkResponse;

// 创建Spot数组
JsonArray spotArray = carparkResponse.createNestedArray("Spot");

// 添加第一个车位对象
JsonObject spot1 = spotArray.createNestedObject();
spot1["LocationId"] = LOCATION_ID;
spot1["SpotId"] = "1";
spot1["Occupied"] = occupied1.isOccupied() ? "Occupied" : "Empty";

// 添加第二个车位对象
JsonObject spot2 = spotArray.createNestedObject();
spot2["LocationId"] = LOCATION_ID;
spot2["SpotId"] = "2";
spot2["Occupied"] = occupied2.isOccupied() ? "Occupied" : "Empty";

// 添加第三个车位对象
JsonObject spot3 = spotArray.createNestedObject();
spot3["LocationId"] = LOCATION_ID;
spot3["SpotId"] = "3";
spot3["Occupied"] = occupied3.isOccupied() ? "Occupied" : "Empty";

// 添加第四个车位对象
JsonObject spot4 = spotArray.createNestedObject();
spot4["LocationId"] = LOCATION_ID;
spot4["SpotId"] = "4";
spot4["Occupied"] = occupied4.isOccupied() ? "Occupied" : "Empty";

serializeJson(carparkResponse, json_string);
Serial.println(json_string);

简化循环写法

如果车位数量固定,可通过循环减少重复代码:

char json_string[256];
StaticJsonDocument<256> carparkResponse;
JsonArray spotArray = carparkResponse.createNestedArray("Spot");

// 存储所有车位的占用状态
bool occupiedStates[] = {occupied1.isOccupied(), occupied2.isOccupied(), occupied3.isOccupied(), occupied4.isOccupied()};

for (int i = 0; i < 4; i++) {
  JsonObject spot = spotArray.createNestedObject();
  spot["LocationId"] = LOCATION_ID;
  spot["SpotId"] = String(i + 1);
  spot["Occupied"] = occupiedStates[i] ? "Occupied" : "Empty";
}

serializeJson(carparkResponse, json_string);
Serial.println(json_string);

4. 是否需要降级到v5?

完全不需要。ArduinoJson 6的API设计更合理,内存管理和性能都优于v5,只要理清数组与对象的创建逻辑,就能轻松实现需求。


内容的提问来源于stack exchange,提问作者Corey673

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 02:57:32