Приветствую, Хабр!
В этой статье я разберу небольшую, но очень полезную тему HTTP запросов в UE. Все будет выполнено строго на C++.
Основная часть
Для отправки запроса нам потребуется Singleton объект выглядящий следующим образом:
FHttpModule* Module = &FHttpModule::Get();
Его мы и будем использовать для запросов. Далее необходимо заполнить запрос параметрами и отправить. Тестовый класс назовем Data и поместим туда пару полей. Сам запрос представляет из себя голый объект, который необходимо обернуть в TSharedRef<>.
USTRUCT() struct FData { GENERATED_BODY() UPROPERTY() int32 ID{-1); UPROPERTY() FString Name{}; }; class ThisClass { //Создание запроса. void MakeRequest() { FHttpModule* Module = &FHttpModule::Get(); TSharedRef<IHttpRequest,ESPMode::ThreadSafe> Request = Module->CreateRequest(); Request->OnProcessRequestComplete().BindRaw(this,&ThisClass::OnPostReceivedResponse);// Подвязываемся на делегат получения запроса. Request->SetURL(GetFullPathURL()); //Выставляем URL. В моем случае - абстрактный путь куда-нибудь Request->SetVerb("POST"); //Непосредственно сам глагол. Request->SetHeader(GetDefaultHeader().Key,GetDefaultHeader().Value);//Опять же, абстрактный хеддер. В вашем случае все зависит от API. Request->SetContentAsString(GetContent());//Абстрактная строка, некогда бывшая Json файлом. (Об этом Ниже). Request->ProcessRequest(); // Отправляем запрос. } ... };
После получения запроса будет вызвана следующая функция:
// Три параметра соответственно: //Request - сам запрос. //Response - ответ. //bWasSuccessful - флаг ошибки. void ThisClass::OnPostReceivedResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) { //Если запрос успешен и ответ валиден. if(bWasSuccessful && Response.Get()) { Response->GetContentAsString(); //Делаем чтонибудь с ответом. } }
Теперь встал вопрос обработки сей строки. Должен признать, когда я только столкнулся с задачей обработать запрос, то сделал максимально просто: написал парсер, который заполняет json и вытаскивает данные из него. Проблема была в том, что для каждого отдельного json’а приходилось писать парсер, что убивало много времени. В конце концов я нашел нативный инструмент, который каждую структуру, помеченную как USTRUCT(), парсит автоматически.
USTRUCT() struct FData { GENERATED_BODY() int32 ID{-1); FString Name{}; }; class ThisClass { void MakeRequest() { FHttpModule* Module = &FHttpModule::Get(); TSharedRef<IHttpRequest,ESPMode::ThreadSafe> Request = Module->CreateRequest(); Request->OnProcessRequestComplete().BindRaw(this,&ThisClass::OnPostReceivedResponse);// Подвязываемся на делегат получения запроса. Request->SetURL(GetFullPathURL()); //Выставляем URL. В моем случае - абстрактный путь куда-нибудь Request->SetVerb("POST"); //Непосредственно сам глагол. Request->SetHeader(GetDefaultHeader().Key,GetDefaultHeader().Value);//Опять же, абстрактный хеддер. В вашем случае все зависит от API. Request->SetContentAsString(GetContent());//Абстрактная строка, некогда бывшая Json файлом. Request->ProcessRequest(); // Отправляем запрос. } void OnPostReceivedResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) { //Если запрос успешен и ответ валиден. if(bWasSuccessful && Response.Get()) { FData Data; //Объект сразу закастится к типу FData и будет помещен в out параметр Data. FJsonObjectConverter::JsonObjectStringToUStruct<FData>(Response->GetContentAsString(),&Data); Data.ID;//Теперь можно использовать эти данные. Data.Name; } } //Таким же образом будет выглядеть преобразование из структуры в строку: FString GetContent(const FData& Object) { FString ReturnStrung; FJsonObjectConverter::UStructToJsonObjectString<FData>(Object,&ReturnStrung); return ReturnString; } };
Послесловие
Тему отправки и принятия запросов можно продолжить и далее, если задаться вопросами: А как мы поймем что получили все отправленные запросы? И как быть в ситуации, когда нам необходимо сохранять множественные данные, вложенные друг в друга? А что если мы захотим отправить 100 запросов, и каждый ответ нужно обработать отдельно? Не хотелось лишний раз перегружать эту статью, посему если вы поддержите, напишу продолжение.
Задавайте вопросы и кидайте предложения для следующих статей.
Буду рад любой адекватной критике.
Спасибо, что читали!
ссылка на оригинал статьи https://habr.com/ru/post/599295/
Добавить комментарий