一.介紹
Json是一種資料對象,資料由鍵值對組成.
1.簡單的Json資料對象:
//{"鍵1":"值1","鍵2":"值2",....}
{"Name":"Tom","Age":"18","Sex":"man"}
2.Json對象作為鍵值對的值
//班長資訊:Json對象作為值
{"MonitorInfo":{"Name":"Tom","Age":"20","Sex":"man"}}
3.Json對象數組
[
//第一個對象
{"Name":"Tom","Age":"18","Sex":"man"},
//第二個對象
{"Name":"Jerry","Age":"17","Sex":"man"},
//第三個對象
{"Name":"Lily","Age":"20","Sex":"woman"}
]
4.Json對象數組作為鍵值對的值
{
//一班
"ClassNum":"1",
//老師叫張三
"TeacherName":"ZhangSan",
//學生數組
"Students":
[
//學生1
{"Name":"Tom","Age":"18","Sex":"man"},
//學生2
{"Name":"Jerry","Age":"17","Sex":"man"},
//學生3
{"Name":"Lily","Age":"20","Sex":"woman"}
]
}
二.UE4 Json使用說明
使用Json子產品需要在Build.cs中将Json子產品導入
PublicDependencyModuleNames.AddRange(
new string[]
{
"Json"
}
);
1.FJsonObject說明
FJsonObject 在UE4裡表示一個Json對象,用于存儲Json資料
(1).初始化方式
TSharedPtr<FJsonObject> Object;
(2)FJsonObject存儲資料的幾種形式
①.将正常類型作為值存儲
//1.存儲資料節點
//(1)SetStringField(FString key,FString value) 存儲一個FString字段
Object->SetStringField(TEXT("Name"),TEXT("Tom"));
/**
*(2)SetNumberField(FString key,double value) 存儲一個浮點型字段
*ps:并沒有SetIntegerField,存儲整形也可以使用這個
*/
Object->SetNumberField(TEXT("Age"),18);
//(3)SetBoolField(FString key,bool value) 存儲一個bool型字段
Object->SetBoolField(TEXT("IsMan"),true);
//截止到次,Object内的資料為{"Name":"Tom","Age":18,"IsMan":true}
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbwxCdh1mcvZ2LcV2Zh1Wa9M3clN2byBXLzN3btg3PwJWZ35iNjRWOwYDNxEjZ5EjYmVzNkVmNlRTNxMWMjZGO1YjNh9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.webp)
實機測試代碼
②.将FJsonObject作為值存儲
//建立一個JsonObject
TSharedPtr<FJsonObject>Object= MakeShareable(new FJsonObject);
//填充字段資訊
Object->SetStringField(TEXT("Name"), TEXT("Tom"));
Object->SetNumberField(TEXT("Age"), 18);
Object->SetBoolField(TEXT("IsMan"), true);
//建立另一個JsonObject作為上面的JsonObject中的一個字段的值
TSharedPtr<FJsonObject>obj = MakeShareable(new FJsonObject);
obj->SetNumberField(TEXT("weight"), 130);
obj->SetNumberField(TEXT("height"), 180);
obj->SetStringField(TEXT("Hobby"), TEXT("Game"));
//将obj作為Object中的Info字段的值
Object->SetObjectField(TEXT("Info"), obj);
實機測試代碼
③.将TArray<TSharedPtr<FJsonValue>>作為值存儲//結構大緻如下
{
"field1":"xx",
"field2":"yy",
"fields":
[
//切記!數組中的元素必須要是字段都一緻的Json對象,所有字段名都得是一樣
{"Name":"tom","Age":18},
{"Name":"jerry","Age":17}
]
}
/**
*SetArrayField(FString key,TArray>value)
*存儲一個數組作為某個字段的值
*/
//1.建立一個空的FJsonValue數組
TArray<TSharedPtr<FJsonValue>>JsonValueArray;
//2.建立兩個FJsonObject作為數組元素
TSharedPtr<FJsonObject>vobj1=MakeShareable(new FJsonObject);
vobj1->SetStringField(TEXT("familymember"),TEXT("Jerry"));
TSharedPtrv<FJsonObject>obj2=MakeShareable(new FJsonObject);
vobj2->SetStringField(TEXT("familymember"),TEXT("John"));
//3.将兩個FJsonObject轉化為FJsonValue,存儲到數組中,到此數組填充完畢
JsonValueArray.Add(MakeShareable(new FJsonValueObject(vobj1)));
JsonValueArray.Add(MakeShareable(new FJsonValueObject(vobj2)));
Object->SetArrayField(TEXT("Famliy"),JsonValueArray);
/**
*截止到此 Object内的資訊
*{
* "Name":"Tom",
* "Age":18,
* "IsMan";true,
* "Family":
* [
* {"familymember":"Jerry"},
* {"familymember":"john"}
* ]
*}
*SetArrayField要比其他的用法稍稍複雜一些,注意了解
*/
實機測試代碼
(3)FJsonObject擷取資料的方式
①.判斷是否擁有某個字段
判斷傳入的字段是否存在,在你想要查詢某個字段的資料但是不确定Json中是否有這個字段時,可以先判斷一下
進階查詢用法,不光可以判斷字段是否存在,還能判斷字段的類型是否一緻
②TryGetXXField
/**
*FieldName:要查詢的字段名
*OutValue:該參數需要傳入一個引用,用于接收查詢到的結果
*傳回一個bool值,查詢到資料傳回true,查詢不到傳回false
*/
TryeGetXXField(FString FieldName,XXType& OutValue);
//假設一個簡單的json對象(僞代碼)
TSharedPtr<FJsonObject>obj={"Name":"Tom","Age":18,"IsMan":true};
FString OutString;
obj->TryGetStringField("Name",OutString); //OutString=Tom;
bool bIsMan=false;
obj->TryGetBoolField("IsMan",bIsMan); //bIsMan=true;
int32 age=0;
//TryGetNumberField可以支援擷取double int32 uint32 int64 類型的數值
obj->TryGetNumberField("Age",age); //age=18;
//obj還能夠獲得FJsonObject和TArray<FJsonValue>數組
③GetXXField
GetNumberField(擷取浮點型數值) return double,
GetBoolField(擷取bool型數值) return bool ,
GetArrayField(擷取FJsonValue數組作為數值) return TArray<TSharedPtr<FJsonValue>>,
GetObjectField(擷取FJsonObject作為數值) return TSharedPtr<FJsonObject>.
說明:
使用TryGet和Get都可以用來擷取資料,如果Json資料的字段是明确的,那麼可以直接使用Get來擷取.如果不确定,可以使用TryGet,根據需求選擇即可
(4)逆序列化(Deserialize)FJsonObject
常用于将一個FString類型的Json資料存入到FJsonObject中
/**
*JsonStr是UE4中的Json資料
*注意!!! 在UE4中需要使用\"(反斜杠+雙引号,轉義字元) 來替代"(雙引号)
*看到 \" 直接在心裡替換成 " 即可
*/
FString JsonStr=TEXT("{\"Name\":\"Tom\",\"Age\":\"18\",\"Sex\":\"man\"}");
//使用工廠類,把FString格式的Json資料存到建立出來的Json Reader中
TSharedRef<TJsonReader<>>Reader = TJsonReaderFactory<>::Create(JsonStr);
//建立一個空的JsonObject(Json對象,因為其基類不是UObject,為了防止記憶體洩漏,使用共享指針)
TSharedPtr<FJsonObject>Object;
//FJsonSerializer 通過Deserialize(逆序列化)拿Reader中存儲的資料來填充空的Json對象
FJsonSerializer::Deserialize(Reader,Object);
//如果逆序列化成功,Json對象IsValid将傳回true,然後我們就可以通過他讀取資料了
if(Object.IsValid())
{
//Json對象通過GetStringField,傳入字段名(鍵),獲得字元串類型的值
FString Name=Object->GetStringField(TEXT("Name"));
//Json對象通過GetIntegerField,傳入字段名(鍵),獲得整形的值
int32 Age=Object->GetIntegerField(TEXT("Age"));
}
實機測試代碼
(5)序列化(Serialize)FJsonObject
常用于将FJsonObject中的資料寫入到FString中
//準備一個用于序列化的FJsonObject
TSharedPtr<FJsonObject>Obj = MakeShareable(new FJsonObject);
Obj->SetStringField("Name", "Tom");
Obj->SetNumberField("Age",18);
Obj->SetBoolField("IsMan", true);
//建立一個空的FString用于接收序列化後的json資料
FString OutString;
TSharedRef<TJsonWriter< TCHAR, TCondensedJsonPrintPolicy<TCHAR>>>Writer = TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&OutString);
//Serializer将Json對象中的資料通過Writer寫入到outstring中
bool bResult=FJsonSerializer::Serialize(Obj.ToSharedRef(),Writer);
if (bResult)
{
UE_LOG(LogTemp, Warning, TEXT("serialize succeeded!! outstring:%s"), *OutString);
}
可以看到空的字元串被寫入了資料
2.FJsonValue說明
FJsonValue在UE4中作為Json資料鍵值對中的值存在
(1).初始化方式
FJsonValue針對每一種Json值類型都進行了派生,引擎不提倡我們直接使用FJsonValue基類,而是提倡我們根據值類型來選擇不同的派生類
派生類如下
1.FJsonValueString
//初始化方式
TSharedPtr<FJsonValue>StrVal = MakeShareable(new FJsonValueString(""));
2.FJsonValueNumber
//初始化方式
TSharedPtr<FJsonValue>numVal = MakeShareable(new FJsonValueNumber(""));
3.FJsonValueBoolean
//初始化方式
TSharedPtr<FJsonValue>boolVal = MakeShareable(new FJsonValueBoolean(false));
4.FJsonValueObject
//初始化方式
TSharedPtr<FJsonObject>Obj = MakeShareable(new FJsonObject);
TSharedPtr<FJsonValue>ObjVal = MakeShareable(new FJsonValueObject(Obj));
5.FJsonValueArray
//初始化方式
TArray<TSharedPtr<FJsonValue>>InArray;
TSharedPtr<FJsonValue>ArrayVal = MakeShareable(new FJsonValueArray(InArray));
還有一些不太常用的派生類,想了解更多可以去Engine\Source\Runtime\Json\Public\Dom\JsonValue.h 中進行檢視
(2)常用節點
①.AsXXX
根據選擇的類型(FJsonValueXXX),可以使用對應的AsXXX來擷取資料内容
比如FJsonValueString 可以使用AsString傳回存儲的字元串
②.TryGetXXX
與AsXXX一樣,根據類型來決定使用具體的TryGet節點擷取資料
3.示例代碼
//建立主體Json對象
TSharedPtr<FJsonObject>TomObj = MakeShareable(new FJsonObject);
//填充正常類型字段資料
TomObj->SetStringField("Name", "Tom");
TomObj->SetNumberField("Age",18);
TomObj->SetBoolField("IsMan", true);
//建立一個子Json對象作為值
TSharedPtr<FJsonObject>InfoObj = MakeShareable(new FJsonObject);
InfoObj->SetNumberField("Height", 180);
InfoObj->SetNumberField("Weight", 70);
TomObj->SetObjectField("Info", InfoObj);
//建立兩個子Json對象,數組的元素
TArray<TSharedPtr<FJsonValue>>ValueArray;
TSharedPtr<FJsonObject>FriendObj1= MakeShareable(new FJsonObject);
TSharedPtr<FJsonObject>FriendObj2 = MakeShareable(new FJsonObject);
//填充子對象資料
FriendObj1->SetStringField("Name", "jerry");
FriendObj1->SetNumberField("IsMan", true);
FriendObj2->SetStringField("Name", "lily");
FriendObj2->SetNumberField("IsMan", false);
ValueArray.Add(MakeShareable(new FJsonValueObject(FriendObj1)));
ValueArray.Add(MakeShareable(new FJsonValueObject(FriendObj2)));
TomObj->SetArrayField("Friends", ValueArray);
FString OutString;
TSharedRef<TJsonWriter< TCHAR, TCondensedJsonPrintPolicy<TCHAR>>>Writer = TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&OutString);
bool bResult=FJsonSerializer::Serialize(TomObj.ToSharedRef(),Writer);
if (bResult)
{
UE_LOG(LogTemp, Warning, TEXT("serialize succeeded!! outstring:%s"), *OutString);
}
作者:埃羅芒阿Sensal
https://www.bilibili.com/read/cv10071665/
出處: bilibili