对于ArduinoJson 5, JsonArray和JsonObject总是通过引用返回,以强调它们驻留在JsonBuffer中。
// ArduinoJson 5
JsonObject& obj = ...
ArduinoJson 6通过返回包装器类:JsonArray、JsonObject和JsonVariant简化了这一点。但是要小心,这些对象的内存仍然保存在其他地方,正如我们将看到的。
// ArduinoJson 6
JsonObject obj = ...
对于ArduinoJson 5,使用JsonObject或JsonArray作为类成员是非常困难的,因为你必须确保JsonBuffer也留在内存中。技巧是也将
JsonBuffer
添加为类成员,但这比它应该的要复杂得多。
ArduinoJson 6用
JsonDocument
的概念替换了JsonBuffer
的概念。JsonDocument
拥有内存并包含对象树的根。您可以看到JsonDocument
是JsonBuffer
和JsonVariant
的组合。
JsonDocument
可以包含任何类型的值,因此需要对其进行强制转换以读取内容。例如:JsonObject root = doc.as<JsonObject>(); // get the root object
类似地,可以将
JsonDocument
重新用于保存任何类型的值。这是通过JsonDocument::to()完成的。例如,你可以像这样重置一个JsonDocument来保存一个JsonObject:
JsonObject root = doc.to<JsonObject>(); // clear and replace with a new JsonObject
最后,你可以将一个JsonDocument赋值给另一个JsonDocument以获得深度拷贝:
DynamicJsonDocument doc2 = doc1; // makes a copy
大多数情况下,您可以跳过对JsonDocument::to()的调用,因为JsonDocument在第一次调用时自动转换为正确的类型。在下面的例子中,JsonDocument隐式地转换为一个对象:
doc["hello"] = "world";
// The above line is equivalent to:
JsonObject root = doc.to<JsonObject>();
root["hello"] = "world";
在下面的例子中,JsonDocument隐式地转换为一个数组:
doc.add("hello");
// The above line is equivalent to:
JsonArray root = doc.to<JsonArray>();
root.add("hello");
当然,自动转换只在JsonDocument为空时发生。
作为JsonBuffer, JsonDocument有两个版本。
// ArduinoJson 5
StaticJsonBuffer<256> jb;
// ArduinoJson 6
StaticJsonDocument<256> doc;
// ArduinoJson 5
DynamicJsonBuffer jb;
// ArduinoJson 6
DynamicJsonDocument doc(1024);
DynamicJsonDocument有一个固定的容量,必须指定给构造函数。与DynamicJsonBuffer不同,DynamicJsonDocument不会自动展开。
对于ArduinoJson 5,您可以通过调用JsonBuffer::parseObject()或JsonBuffer::parseArray()来调用JSON解析器。
// ArduinoJson 5
JsonObject& obj = jb.parseObject(input);
// ArduinoJson 6
deserializeJson(doc, input);
每次调用deserializeJson()时,都会清除JsonDocument。该特性允许多次重用同一个JsonDocument,这在JsonBuffer中是不可能的。请不要将此视为使用全局JsonDocument的邀请,因为这是一个不优雅且低效的解决方案。
对于ArduinoJson 5,您使用JsonObject::success()或JsonArray::success()来检查解析是否成功,并且您没有关于哪里出错的信息。
// ArduinoJson 5
JsonObject& obj = jb.parseObject(input);
if (!obj.success()) {
Serial.println("parseObject() failed");
return;
}
// ArduinoJson 6
auto error = deserializeJson(doc, input);
if (error) {
Serial.print(F("deserializeJson() failed with code "));
Serial.println(error.c_str());
return;
}
// ArduinoJson 5
obj.printTo(Serial);
// ArduinoJson 6
serializeJson(doc, Serial);
类似地,您可以调用serializeJsonPretty()来生成经过美化的JSON文档。
使用ArduinoJson 5,您可以通过调用JsonArray::measureLength()或JsonObject::measureLength()来计算序列化文档的长度。
// ArduinoJson 5
size_t len = obj.measureLength();
在ArduinoJson 6中,可以调用measureJson()。
// ArduinoJson `6`
size_t len = measureJson(doc);
类似地,measureJsonPretty()替换JsonArray::measurePrettyLength()和JsonObject::measureJsonPretty()。
ArduinoJson 5没有强制输入以零结束,但强烈建议这样做以防止缓冲区溢出。
使用ArduinoJson 6,您可以向deserializeJson()传递一个额外的参数,以指定输入的最大大小。示例:
// ArduinoJson 6
deserializeJson(doc, input, inputSize);
使用ArduinoJson 5,您可以通过传递一个可选参数给JsonBuffer::parseArray()或JsonBuffer::parseObject()来更改嵌套限制。
// ArduinoJson 5
JsonObject& obj = jb.parseObject(input, 20);
// ArduinoJson 6
deserializeJson(doc, input, DeserializationOption::NestingLimit(20));
ArduinoJson 6支持MessagePack文档的序列化和反序列化。
但是,它目前不支持MessagePack的以下特性:
bin format
timestamp
// ArduinoJson 6
serializeMsgPack(doc, Serial);
类似地,要对MessagePack文档进行反序列化,就像对JSON文档进行反序列化一样,只不过调用的是deserializeMsgPack()而不是deserializeJson()。例如:
// ArduinoJson 6
deserializeMsgPack(doc, input);
在ArduinoJson 5中,当您想要插入一个预格式化的JSON块时,您可以调用RawJson()。
// ArduinoJson 5
obj["raw"] = RawJson("[1,2,3]");
// ArduinoJson 6
doc["raw"] = serialized("[1,2,3]");
在ArduinoJson 5中,当您枚举JsonObject中的成员时,您将收到一个具有两个成员变量key和value的JsonPair。第一个是const char*,第二个是JsonVariant。
// ArduinoJson 5
for (JsonPair p : obj) {
const char* key = p.key;
JsonVariant value = p.value;
...
}
// ArduinoJson 6
for (JsonPair p : obj) {
const char* key = p.key().c_str();
JsonVariant value = p.value();
...
}
使用ArduinoJson 5,您可以轻松地使用JsonArray::copyFrom()和JsonArray::copyTo()在JsonArray和常规数组之间复制值。
int values[] = {1,2,3};
// ArduinoJson 5
arr.copyFrom(values);
arr.copyTo(values);
在6.9版中,必须调用copyArray()。这两种操作只有一个函数。第一个参数是源,第二个是目的地。
int values[] = {1,2,3};
// ArduinoJson 6
copyArray(values, arr);
copyArray(arr, values);
对于ArduinoJson 5, JsonVariant具有值语义。可以在没有JsonBuffer的情况下创建实例。
// ArduinoJson 5
JsonVariant var = 42;
对于ArduinoJson 6, JsonVariant有引用语义,像JsonArray和JsonObject。你需要一个JsonDocument来初始化一个JsonVariant。
// ArduinoJson 6
JsonVariant var = doc.to<JsonVariant>();
var.set(42);
在ArduinoJson 5中,你可以通过调用success()来检查数组或对象是否有效:
// ArduinoJson 5
if (!obj.success()) ...
// ArduinoJson 6
if (obj.isNull()) ...
isNull()与success()并不完全相反:当值定义为null时,isNull()和success()都返回true。
// ArduinoJson 5
DynamicJsonBuffer jb;
JsonObject& obj = jb.parseObject(json);
if (!obj.success())
return;
int value = obj["value"];
// ArduinoJson 6
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, json);
if (error)
return;
int value = doc["value"];
// ArduinoJson 5
DynamicJsonBuffer jb;
JsonObject& obj = jb.createObject();
obj["key"] = "value";
obj["raw"] = RawJson("[1,2,3]");
obj.printTo(Serial);
// ArduinoJson 6
DynamicJsonDocument doc(1024);
doc["key"] = "value";
doc["raw"] = serialized("[1,2,3]");
serializeJson(doc, Serial);