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 One
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FDownloadProgressDelegate,
const int32&, ReceivedDataInBytes,
const int32&, TotalDataInBytes,
const TArray<uint8>&, BinaryData
);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDownloadDelegate);
#pragma endregion
#pragma region Two
UENUM(BlueprintType)
enum class EPTRequestVerb : uint8
{
GET,
POST
};
#pragma endregion
/**
*
*/
UCLASS()
class PIECETOGETHERTOOLS_API UAsyncHttpObject : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
#pragma region One
UFUNCTION(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 Two
UFUNCTION(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;
}
//设置URL
request->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(); // 手动GC
return AsyncHttpObject;
}
void UAsyncHttpObject::AsyncRequestHandle(FHttpRequestPtr request, FHttpResponsePtr response, bool bWasSuccessful)
{
RemoveFromRoot(); // 手动GC
if (bWasSuccessful && response.IsValid() && EHttpResponseCodes::IsOk(response->GetResponseCode()))
{
// 获得返回的json数据
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(response->GetContentAsString());
// 把FString转成TCHAR
TCHAR* serializedChar = response->GetContentAsString().GetCharArray().GetData();
// 解决中文乱码问题,服务端也是utf-8
TCHAR_TO_UTF8(serializedChar);
FString myData(serializedChar);
// 创建Json对象
TSharedPtr<FJsonObject> JsonObject;
// 反序列化json
bool 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.
.h
UFUNCTION(BlueprintCallable, Category = "Vince | AsyncHttp", meta = (WorldContext = "WorldContextObject"))
static void XieJson(FString& outjsonStr, const UObject* WorldContextObject);
.cpp
void 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转成TCHAR
TCHAR* serializedChar = response->GetContentAsString().GetCharArray().GetData();
// 解决中文乱码问题,服务端也是utf-8
TCHAR_TO_UTF8(serializedChar);
FString myData(serializedChar);
// 创建Json对象
TSharedPtr<FJsonObject> JsonObject;
// 反序列化json
bool 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");
}