HTTP请求与回复
2024年5月11日 2024年5月11日
预备工作
-
添加依赖
1PrivateDependencyModuleNames.AddRange( 2 new string[] 3 { 4 "CoreUObject", 5 "Engine", 6 "Slate", 7 "SlateCore", 8 // ... add private dependencies that you statically link with here ... 9 "HTTP", 10 } 11 );
-
头文件
1#include "HTTP.h"
FHttpRequestPtr,FHttpResponsePtr,FHttpRequestRef和FHttpResponseRef的定义在Intefaces/IHttpRequest.h中
发送请求
1FString Token = TEXT("<token string>"); 2 3FString Auth = FString::Printf(TEXT("Bearer %s"), *Token); 4FString Url = FString::Printf(TEXT("<url string>")); 5 6FHttpRequestRef Req = FHttpModule::Get().CreateRequest(); 7Req->SetTimeout(1050); 8Req->SetURL(Url); 9Req->SetVerb(TEXT("GET")); 10Req->SetHeader(TEXT("Authorization"), Auth); 11 12// Req->SetHeader(TEXT("content-Type"), TEXT("application/json")); 13// Req->SetContentAsString(TEXT("<content string>")); 14 15// 此处添加绑定 16 17Req->ProcessRequest();
绑定回调函数
1Req->OnProcessRequestComplete().BindUObject(this, &UFirstGISubsystem::OnHttpResponse);
1void UFirstGISubsystem::OnHttpResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bSuccess) 2{ 3 if (bSuccess && Response.IsValid()) 4 { 5 int32 ResponseCode = Response->GetResponseCode(); 6 FString ResponseContent = Response->GetContentAsString(); 7 8 UE_LOG(LogTemp, Display, TEXT("[%s][%d]Response Content: %s"), *FString(__FUNCTION__), __LINE__, *ResponseContent); 9 } 10 else { UE_LOG(LogTemp, Warning, TEXT("[%s][%d]Invalid response"), *FString(__FUNCTION__), __LINE__); } 11}
绑定lambda
1Req->OnProcessRequestComplete().BindLambda( 2 [](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bSuccess) 3 { 4 if (bSuccess && Response.IsValid()) 5 { 6 int32 ResponseCode = Response->GetResponseCode(); 7 FString ResponseContent = Response->GetContentAsString(); 8 // TArray<uint8> ResponseContent = Response->GetContent(); 9 10 UE_LOG(LogTemp, Display, TEXT("[%s][%d]Response Content: %s"), *FString(__FUNCTION__), __LINE__, *ResponseContent); 11 } 12 else { UE_LOG(LogTemp, Warning, TEXT("[%s][%d]Invalid response"), *FString(__FUNCTION__), __LINE__); } 13 });
注意
-
Http的请求与回复默认异步,很合理。但如果本身就由另外的线程发送请求,在发送Http请求后等待回复,更易管理
使用FEvent可以实现同步 -
默认在主线程发送Http请求,可设置为子线程发送
5.1
不支持,5.3
可以1Req->SetDelegateThreadPolicy(EHttpRequestDelegateThreadPolicy::CompleteOnHttpThread);
POST提交格式
Content Type | 写内容方法 | 取内容方法 | |
---|---|---|---|
application/json | FString | SetContentAsString | GetContentAsString |
multipart/form-data | TArray<uint8> | SetContent | GetContent |
定义边界
文本内容任意,需要特殊的开始和结束界定
-
边界字符串
可以使用时间戳,也可以使用GUID1FString Boundary = TEXT("-----") + FString::FromInt(FDataTime::Now().ToUnixTimestamp());
-
开始边界和结束边界
以\r\n
开始和结束1FString BeginBoundary = TEXT("\r\n--") + Boundary + TEXT("\r\n"); 2FString EndBoundary = TEXT("\r\n--") + Boundary + TEXT("--\r\n");
携带参数
-
头部说明
1FString ParamHeader = TEXT("Content-Disposition: form-data; name=\"<param name>\"; \r\n");
-
参数类型
1FString ParamContentType = TEXT("Content-Type: text/plain\r\n\r\n");
-
参数文本格式
Content-Disposition: form-data; name="<param name>"; \r\n Content-Type: text/plain\r\n\r\n <参数值>
特例:文件类型参数
-
头部说明
1FString ParamHeader = TEXT("Content-Disposition: form-data; name=\"file\"; filename=\"<file name>\" \r\n");
-
参数类型
1FString ParamContentType = TEXT("Content-Type: application/octet-stream\r\n\r\n");
-
参数文本格式
Content-Disposition: form-data; name="file"; filename="<file name>" \r\n Content-Type: application/octet-stream\r\n\r\n <文本内容>
完整文本
<BeginBoundary> <参数1> <BeginBoundary> <参数2> <EndBoundary>
设置Http请求头部参数
-
长度
1Req->SetHeader(TEXT("Content-Length"), TEXT("<Content length>"));
-
负载类型和边界
1FString ContentType = FString::Printf(TEXT("multipart/form-data; boundary=%s"), *Boundary);