JSON序列化与解析
2024年4月21日 2024年4月21日
JavaScript Object Notation
JSON序列化:将结构体序列化为字符串
JSON解析:将JSON字符串解析为方便读取的数据结构
虚幻JSON插件
-
Json Blueprint Utilities
知乎 - 虚幻官方Json插件 - Json Blueprint Utilities -
Json
Json - 5.3Engine/Source/Runtime/Json
-
JsonUtilities
JsonUtilities - 5.3Engine/Source/Runtime/JsonUtilities
可以这么理解,JsonUtilities在Json的基础上进行了封装,具体使用时,即使包含了JsonUtilities插件,也可能出现链接报错,这个时候包含Json插件即可
在(.Build.cs)的PrivateDependencyModuleNames添加依赖插件
JSON使用场景
虽然分了两种,使用起来却没什么不同
具体所需操作直接在头文件中寻找
头文件 | ||
---|---|---|
JsonObjectWrapper | JsonUtilities/Public/JsonObjectWrapper.h | 将数据解析为JsonObject |
JsonObjectConverter | JsonUtilities/Public/JsonObjectConverter.h | 将JsonObject转换成结构体对象 |
JsonObject | Json/Public/DOM/JsonObject.h | 可以从中取出指定字段值 |
JsonValue | Json/Public/DOM/JsonValue.h | 给出字段值的读取方法并取出 |
JSON格式的数据
以下示例仅包含了Utilities插件
-
将文件内容读取到字符串
1FString Content; 2FFileHelper::LoadFileToString(Content, *FilePath);
-
将字符串解析为JsonObject
1#include "JsonUtilities.h" 2 3FJsonObjectWrapper Wrapper; 4Wrapper.JsonObjectFromString(Content); 5 6auto Obj = Wrapper.JsonObject;
-
取出给定字段值
1FString FieldName = TEXT("FieldName"); 2auto JsonValue = Wrapper.JsonObject->TryGetField(FieldName);
-
读取字段值
1TArray<TSharedPtr<FJsonValue>> *ValueArray; 2JsonValue->TryGetArray(ValueArray);
HTTP请求与回复
同时包含了Json和JsonUtilities插件
涉及到将结构体序列化成JSON字符串,将JSON字符串存储到结构体对象中
将结构体序列化成JSON字符串
1#include "JsonUtilities.h" 2 3USTRUCT() 4struct FRequestItemFormat 5{ 6 GENERATED_USTRUCT_BODY() 7 8 UPROPERTY() 9 FString Index; 10 11 UPROPERTY() 12 FString ElementField; 13}; 14 15USTRUCT() 16struct FRequestFormat 17{ 18 GENERATED_USTRUCT_BODY() 19 20 UPROPERTY() 21 FString Field1; 22 23 UPROPERTY() 24 FString Field2; 25 26 UPROPERTY() 27 TAarray<FRequestItemFormat> MemberList; 28}; 29 30FRequestFormat JsonStruct = { 31 TEXT("字段1的值"), 32 TEXT("字段2的值"), 33 { 34 {TEXT("元素1的索引"), TEXT("元素1的字段值")}, 35 {TEXT("元素2的索引"), TEXT("元素2的字段值")} 36 } 37}; 38 39/* 40{ 41 "field1" : "字段1的值", 42 "field2" : "字段2的值", 43 "memberList" : [ 44 { 45 "index" : "元素1的索引", 46 "elementField" : "元素1的字段值" 47 }, 48 { 49 "index" : "元素2的索引", 50 "elementField" : "元素2的字段值" 51 } 52 ] 53} 54*/ 55 56// 传入指向结构体的指针,将输出存储到JsonContent引用 57FString JsonContent; 58FJsonObjectConverter::UStructToJsonObjectString(FRequestFormat::StaticStruct(), &JsonStruct, JsonContent);
字段值类型为JsonObject
-
取出JsonObject,此时使TSharedPtr指向JsonObject对象
1TSharedPtr<FJsonObject> *JsonObjPtr = nullptr; 2JsonValue->TryGetObject(JsonObjPtr);
-
将JsonObject解析为结构体对象,此时需传入绑定到JsonObject的TSharedRef对象
1USTRUCT() 2struct FReplyFormat 3{ 4 GENERATED_USTRUCT_BODY() 5 6 UPROPERTY() 7 FString Field1; 8 9 UPROPERTY() 10 FString Field2; 11}; 12 13FReplyFormat Reply; 14FJsonObjectConverter::JsonObjectToUStruct((*JsonObjPtr).ToSharedRef(), FReplyFormat::StaticStruct(), &Reply);
注意
-
支持枚举类型作为字段值类型,解析时,使用枚举成员的变量值
-
使用UPROPERTY宏标记了的数据成员才会参与JSON序列化与解析
-
虚幻命名规则约定了首字母大写,序列化时,会自动将其转换为小写
-
如果字段类型为int64,JSON字符串里可能是科学计数表示,但不影响判等