delphi Отправить файл в виде байтового массива в службу Rest

Я использую Delphi 10.1 Berlin

Я хочу отправить данные изображения как TBytes в службу Rest с помощью TRestRequest, но я не смог найти способ передать TBytes методу TRestRequest.AddBody() или любому другому методу.

POST http://myserver:1111//Openxxx/RecxxxLxxxPxxxx HTTP/1.1
Content-Type: text/json
Host: myserver:1111
Content-Length: 28892
Expect: 100-continue
Connection: Keep-Alive

[255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,1,0,1,0,0,255,219,0,132,0,9,
...
...
...
130,130,252,168,127,164,63,164,41,109,204,245,62,106,51,135,12,146,63,255,217]

person Enes Köroğlu    schedule 15.03.2017    source источник


Ответы (2)


TRESTRequest.AddBody() имеет перегрузку, которая принимает TStream в качестве входных данных. Вы можете обернуть свой TBytes в TStream с помощью класса TBytesStream.

procedure TForm1.Button1Click(Sender: TObject);
var
  ABytes: TBytes;
  AStream: TBytesStream;
begin
  ABytes := ...;
  try
    AStream := TBytesStream.Create(ABytes);
    RESTRequest1.AddBody(AStream, ctIMAGE_JPEG); 
    RESTRequest1.Execute;
  finally
    AStream.Free;
  end;
end;

В качестве альтернативы используйте вместо этого TRESTRequestParameterList.AddItem, который имеет перегрузку для TBytes :

procedure TForm1.Button1Click(Sender: TObject);
var
  ABytes: TBytes;
begin
  ABytes := ...
  RESTRequest1.Params.AddItem('body', ABytes, pkGETorPOST, [poDoNotEncode], ctIMAGE_JPEG);
  RESTRequest1.Execute;
end;

При этом я считаю TRESTClient слишком сложным и ошибочным / ограничивающим. В большинстве случаев Indy TIdHTTP проще в использовании, например:

procedure TForm1.Button1Click(Sender: TObject);
var
  ABytes: TBytes;
  AStream: TBytesStream;
begin
  ABytes := ...;
  try
    AStream := TBytesStream.Create(ABytes);
    IdHTTP1.Request.ContentType := 'image/jpeg';
    IdHTTP1.Post('http://myserver:1111//Openxxx/RecxxxLxxxPxxxx', AStream);
  finally
    AStream.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  IdHTTP1.Request.ContentType := 'image/jpeg';
  IdHTTP1.Post('http://myserver:1111//Openxxx/RecxxxLxxxPxxxx', 'image.jpg');
end;
person Remy Lebeau    schedule 15.03.2017
comment
Я пробовал, как показано ниже, но без изменений. codevar ABytes: ТБайт; AStream: TBytesStream; begin ABytes: = TFile.ReadAllBytes ('images.jpg'); AStream: = TBytesStream.Create (ABytes); RESTRequest1.ClearBody; RESTRequest1.AddBody (AStream); // ByteArrayToString (ABytes)); RESTRequest1.Execute; конец; code - person Enes Köroğlu; 16.03.2017
comment
Создает сообщение вроде: ‹br/› POST http://s-lywms:2364//OpenAlpr/RecognizeLicensePlates HTTP/1.1 Content-Type: application/x-www-form-urlencoded Accept: application/json, text/plain; q=0.9, text/html;q=0.8, Accept-Charset: UTF-8, *;q=0.8 User-Agent: Embarcadero RESTClient/1.0 Connection: Keep-Alive Content-Length: 0 Host: s-lywms:2364 - person Enes Köroğlu; 16.03.2017
comment
Я не могу ответить на этот вопрос, не копаясь в исходном коде клиента REST. Но почему вы читаете файл в TBytes, завернутый в TStream, а не просто используете TFileStream напрямую? var AStream: TFileStream; begin AStream := TFileStream.Create('images.jpg', fmOpenRead); RESTRequest1.ClearBody; RESTRequest1.AddBody(AStream); RESTRequest1.Execute; AStream.Free; end; - person Remy Lebeau; 16.03.2017
comment
Привет, Ремми, сначала я хочу поблагодарить вас, но ваше решение создает пустой запрос REST. Нет данных о теле. И я хочу напомнить, что я не поставщик / провайдер этой услуги, я пытаюсь написать, что мой клиент и провайдер ожидают байтовый массив (я думаю, это означает TBytes). POST http://s-lywms:2364//OpenAlpr/RecognizeLicensePlates HTTP/1.1 Content-Type: application/x-www-form-urlencoded Accept: application/json, text/plain; q=0.9, text/html;q=0.8, Accept-Charset: UTF-8, *;q=0.8 User-Agent: Embarcadero RESTClient/1.0 Connection: Keep-Alive Content-Length: 0 Host: s-lywms:2364 - person Enes Köroğlu; 17.03.2017
comment
@RemyLebeau Как использовать RESTRequest1.AddBody (... если есть более одного параметра rg. Первый параметр - это имя изображения, второй поток памяти blob изображения? - person user_odoo; 13.04.2021

Я решил свою проблему, как показано ниже:

function BytesToStr(abytes: tbytes): string;
var
  abyte: byte;
begin
   for abyte in abytes do
   begin
      Result := result + IntToStr(abyte) + ',';
   end;
   Result := '[' + Copy(Result, 1, Length(Result) - 1) + ']';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   ABytes: TBytes;
begin
   ABytes := TFile.ReadAllBytes('images.jpg');
   RESTRequest1.Params.AddItem('body', BytesToStr(ABytes), pkREQUESTBODY, [], ctAPPLICATION_JSON);
   RESTRequest1.Execute;
end;
person Enes Köroğlu    schedule 16.03.2017