c++参考链接
UE4 开发如何使用 Http 请求_wx61ae2f5191643的技术博客_51CTO博客
虚幻引擎:UEC++如何对JSON文件进行读写?-CSDN博客
UE4 HTTP使用
官方免费插件
VaRest
在代码插件创建的VaRest - 虚幻引擎商城
UE5在蓝图中使用Varest插件Get,Post两种常见请求方式_慢慢沉的博客-CSDN博客
UE4使用VaRest插件请求httpAPI以及解析json格式数据_ue4 varest-CSDN博客
示例代码
里面有部分是我测试Http下载文件的代码.所以实际效果很乱.自行理解删减
- 单纯的Http请求.返回值因为与下面这个下载是同一个Class里面所以是混乱的
- Http下载文件 UE Http下载文件/解压压缩包_Vince丶的博客-CSDN博客
xxx..Build.cs"HTTP",
"Json",
"JsonUtilities"
.h#pragma once#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "Interfaces/IHttpRequest.h"
#include "AsyncHttpObject.generated.h"#pragma region OneDECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FDownloadProgressDelegate,const int32&, ReceivedDataInBytes,const int32&, TotalDataInBytes,const TArray<uint8>&, BinaryData
);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDownloadDelegate);#pragma endregion#pragma region TwoUENUM(BlueprintType)
enum class EPTRequestVerb : uint8
{GET,POST
};#pragma endregion
/****/
UCLASS()
class PIECETOGETHERTOOLS_API UAsyncHttpObject : public UBlueprintAsyncActionBase
{GENERATED_BODY()public:#pragma region OneUFUNCTION(BlueprintCallable, Category = "Vince | AsyncHttp", meta = (BlueprintInternalUseOnly = "true"))static UAsyncHttpObject* AsyncHttpDownload(const FString& URL, FString fileSavePath, FString ileSaveName);void DownloadRequestStart(const FString& url);void DownloadRequestHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful);void DownloadProgress(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived);//输出节点UPROPERTY(BlueprintAssignable, Category = "Vince | AsyncHttp")FDownloadProgressDelegate OnProgressUpdate; //最好把有参数的放在前面,不然参数在蓝图节点有时候被吃掉了//输出节点UPROPERTY(BlueprintAssignable, Category = "Vince | AsyncHttp")FDownloadDelegate OnSucc;//输出节点UPROPERTY(BlueprintAssignable, Category = "Vince | AsyncHttp")FDownloadDelegate OnFailed;#pragma endregion#pragma region TwoUFUNCTION(BlueprintCallable, Category = "Vince | AsyncHttp", meta = (BlueprintInternalUseOnly = "true"))static UAsyncHttpObject* ConnectAsyncHttp(EPTRequestVerb verb, const FString& URL);FString MassageBody = TEXT("");void AsyncRequestHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful);#pragma endregion
.cpp// Fill out your copyright notice in the Description page of Project Settings.#include "AsyncHttpObject.h"
#include "HttpModule.h"
#include "Interfaces/IHttpResponse.h"
#include "Misc/Paths.h"
#include "HAL/PlatformFileManager.h"
#include "GenericPlatform/GenericPlatformFile.h"#pragma region One//存储目录
FString FileSavePath =TEXT("");//存储名字
FString FileSaveName = TEXT("");UAsyncHttpObject* UAsyncHttpObject::AsyncHttpDownload(const FString& URL, FString fileSavePath, FString fileSaveName)
{UAsyncHttpObject* AsyncHttpObject = NewObject<UAsyncHttpObject>();AsyncHttpObject->DownloadRequestStart(URL);FileSavePath = fileSavePath;FileSaveName = fileSaveName;return AsyncHttpObject;
}//开始请求下载
void UAsyncHttpObject::DownloadRequestStart(const FString& url)
{TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request = FHttpModule::Get().CreateRequest();request->SetVerb("GET");request->SetURL(url);request->OnProcessRequestComplete().BindUObject(this, &UAsyncHttpObject::DownloadRequestHandle); //请求回调request->OnRequestProgress().BindUObject(this, &UAsyncHttpObject::DownloadProgress);// 下载进度request->ProcessRequest();RemoveFromRoot(); // 手动GC
}请求回调
void UAsyncHttpObject::DownloadRequestHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful)
{RemoveFromRoot();if (bWasSuccessful && response.IsValid() && EHttpResponseCodes::IsOk(response->GetResponseCode())){if (response->GetContentLength() > 0) {TArray<uint8> EmptyData;OnProgressUpdate.Broadcast(response->GetContentLength(), response->GetContentLength(), EmptyData);}//FString FileSavePath = FPaths::ProjectDir() + "/download/gameplay.png";//下载返回类型设置FString sType, SLeft, SRight;sType = response->GetHeader(TEXT("Content-Type"));sType.Split("/",&SLeft,&SRight);FileSaveName.Append(FString::Printf(TEXT(".%s"), *SRight)) ;//组合 存储地址FileSavePath = FPaths::Combine(FileSavePath, FileSaveName);FString Path, Filename, Extension;FPaths::Split(FileSavePath, Path, Filename, Extension);IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();if (!PlatformFile.DirectoryExists(*Path)){if (!PlatformFile.CreateDirectoryTree(*Path)){UE_LOG(LogTemp, Error, TEXT("Create Directory Failed!"));OnFailed.Broadcast();return;}}IFileHandle* FileHandle = PlatformFile.OpenWrite(*FileSavePath);if (FileHandle){FileHandle->Write(response->GetContent().GetData(), response->GetContentLength());delete FileHandle;OnSucc.Broadcast();return;}else {UE_LOG(LogTemp, Error, TEXT("Save File Failed!"));OnFailed.Broadcast();return;}}UE_LOG(LogTemp, Error, TEXT("download File Failed!"));OnFailed.Broadcast();return;
}// 下载进度
void UAsyncHttpObject::DownloadProgress(FHttpRequestPtr request, int32 bytesSent, int32 bytesReceived)
{if (request->GetResponse()->GetContentLength() > 0){TArray<uint8> EmptyData;OnProgressUpdate.Broadcast(bytesReceived, request->GetResponse()->GetContentLength(), EmptyData);}
}UAsyncHttpObject* UAsyncHttpObject::ConnectAsyncHttp(EPTRequestVerb verb, const FString& URL)
{UAsyncHttpObject* AsyncHttpObject = NewObject<UAsyncHttpObject>();AsyncHttpObject->MassageBody = "";if (URL.IsEmpty()){// AsyncHttpObject->OnFailed.Broadcast("URL Is Null");}TSharedRef<IHttpRequest, ESPMode::ThreadSafe> request = FHttpModule::Get().CreateRequest();switch (verb){case EPTRequestVerb::GET://设置请求方式request->SetVerb(TEXT("GET"));//设置头request->SetHeader(TEXT("Content-Type"), TEXT("application/json;charset=utf-8"));break;case EPTRequestVerb::POST:request->SetVerb(TEXT("POST"));request->SetHeader(TEXT("Content-Type"), TEXT("application/x - www-form-urlencoded"));break;default:break;}//设置URLrequest->SetURL(URL);//绑定回调request->OnProcessRequestComplete().BindUObject(AsyncHttpObject, &UAsyncHttpObject::AsyncRequestHandle); //请求回调request->OnRequestProgress().BindUObject(AsyncHttpObject, &UAsyncHttpObject::DownloadProgress);// 下载进度内容TSharedRef<FJsonObject> pJsonObject = MakeShared<FJsonObject>();TSharedRef<FJsonObject> pJsonObject1 = MakeShared<FJsonObject>();////pJsonObject->SetStringField("TD", URL);//pJsonObject->SetStringField("TD1", "123");//pJsonObject1->SetObjectField("TDB",pJsonObject);//FString OutputString;//TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);//FJsonSerializer::Serialize(pJsonObject1, Writer);Json内容设置//request->SetContentAsString(OutputString);//GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, OutputString, false);//请求request->ProcessRequest();AsyncHttpObject->RemoveFromRoot(); // 手动GCreturn AsyncHttpObject;}void UAsyncHttpObject::AsyncRequestHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful)
{RemoveFromRoot(); // 手动GCif (bWasSuccessful && response.IsValid() && EHttpResponseCodes::IsOk(response->GetResponseCode())){// 获得返回的json数据TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(response->GetContentAsString());// 把FString转成TCHARTCHAR* serializedChar = response->GetContentAsString().GetCharArray().GetData();// 解决中文乱码问题,服务端也是utf-8TCHAR_TO_UTF8(serializedChar);FString myData(serializedChar);// 创建Json对象TSharedPtr<FJsonObject> JsonObject;// 反序列化jsonbool bIsOk = FJsonSerializer::Deserialize(JsonReader, JsonObject);// 判断是否反序列化成功if (bIsOk){FString data = JsonObject->GetStringField("city");//FWHelper::Debug(data);UE_LOG(LogTemp, Warning, TEXT("%s"), *data);UE_LOG(LogTemp, Warning, TEXT("%s"), *myData);FString OutputString;TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> Writer = TJsonWriterFactory<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>::Create(&OutputString);FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); //Serialize:把内存中的对象转为便于存储和传输的数据//打印UE_LOG(LogNet, Warning, TEXT("output 1:\n%s"), *OutputString);TSharedPtr<FJsonObject, ESPMode::ThreadSafe> Object = JsonObject->GetObjectField(TEXT("name"));TSharedPtr<FJsonObject, ESPMode::ThreadSafe> ObjectField = Object->GetObjectField(TEXT("realtime"));FString StringField = ObjectField->GetStringField("text");}}
}#pragma endregion//void UAsyncHttpObject::XieJson(FString& outjsonStr, const UObject* WorldContextObject)
//{
// // 声明一个存储Json内容的字符串
// FString JsonStr;
// //GetJSONStr(JsonStr,WorldContextObject);
//
// // 创建一个Json编写器
// TSharedRef<TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>> JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&JsonStr);
// //TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&JsonStr);
//
// // 声明Json对象写入开始
// JsonWriter->WriteObjectStart();
// JsonWriter->WriteValue(TEXT("Time"), TEXT("21"));
//
// // 声明Json数组写入开始
// JsonWriter->WriteArrayStart(TEXT("Data"));
// for (int i = 0; i < 2; i++)
// {
// JsonWriter->WriteObjectStart();
// JsonWriter->WriteValue(TEXT("key"), i);
// JsonWriter->WriteObjectEnd();
// }
// JsonWriter->WriteArrayEnd();
//
// JsonWriter->WriteObjectEnd();
// // 停止写入
// JsonWriter->Close();
//
// UE_LOG(LogTemp, Warning, TEXT("%s"), *JsonStr);
// outjsonStr = JsonStr;
//
// GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, outjsonStr, false);
//}
写入Http请求内容示例
写入Http请求Json内容我自己测试的可以有2种习惯.看自己习惯.c++能力有限.可能描述有误.自行理解把.
第一种直接给 FJsonObject 直接写入 .最后在转成Fstring内容
TSharedRef<FJsonObject> pJsonObject = MakeShared<FJsonObject>();
TSharedRef<FJsonObject> pJsonObject1 = MakeShared<FJsonObject>();pJsonObject->SetStringField("TD", URL);
pJsonObject->SetStringField("TD1", "123");//pJsonObject1->SetObjectField("TDB",pJsonObject);
FString OutputString;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
FJsonSerializer::Serialize(pJsonObject1, Writer);//Json内容设置
request->SetContentAsString(OutputString);GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, OutputString, false);
第二种 创建一个Json编写器 直接编写Json..hUFUNCTION(BlueprintCallable, Category = "Vince | AsyncHttp", meta = (WorldContext = "WorldContextObject"))
static void XieJson(FString& outjsonStr, const UObject* WorldContextObject);.cppvoid UPieceTogetherToolsBPLibrary::XieJson(FString& outjsonStr, const UObject* WorldContextObject)
{// 声明一个存储Json内容的字符串FString JsonStr;//GetJSONStr(JsonStr,WorldContextObject);// 创建一个Json编写器TSharedRef<TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>> JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&JsonStr);//TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&JsonStr);// 声明Json对象写入开始JsonWriter->WriteObjectStart();JsonWriter->WriteValue(TEXT("Time"), TEXT("21"));// 声明Json数组写入开始JsonWriter->WriteArrayStart(TEXT("Data"));for (int i = 0; i < 2; i++){JsonWriter->WriteValue(TEXT("key"), i);}JsonWriter->WriteArrayEnd();JsonWriter->WriteObjectEnd();// 停止写入JsonWriter->Close();UE_LOG(LogTemp, Warning, TEXT("%s"), *JsonStr);outjsonStr = JsonStr;GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, outjsonStr, false);
}
Http接收回调解析数据示例
.cpp// 获得返回的json数据TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(response->GetContentAsString());// 把FString转成TCHARTCHAR* serializedChar = response->GetContentAsString().GetCharArray().GetData();// 解决中文乱码问题,服务端也是utf-8TCHAR_TO_UTF8(serializedChar);FString myData(serializedChar);// 创建Json对象TSharedPtr<FJsonObject> JsonObject;// 反序列化jsonbool bIsOk = FJsonSerializer::Deserialize(JsonReader, JsonObject);// 判断是否反序列化成功if (bIsOk){FString data = JsonObject->GetStringField("city");//FWHelper::Debug(data);UE_LOG(LogTemp, Warning, TEXT("%s"), *data);UE_LOG(LogTemp, Warning, TEXT("%s"), *myData);FString OutputString;TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> Writer = TJsonWriterFactory<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>::Create(&OutputString);FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); //Serialize:把内存中的对象转为便于存储和传输的数据//打印UE_LOG(LogNet, Warning, TEXT("output 1:\n%s"), *OutputString);TSharedPtr<FJsonObject, ESPMode::ThreadSafe> Object = JsonObject->GetObjectField(TEXT("name"));TSharedPtr<FJsonObject, ESPMode::ThreadSafe> ObjectField = Object->GetObjectField(TEXT("realtime"));FString StringField = ObjectField->GetStringField("text");}