如何用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
相关产品推荐
相关产品推荐

