【问题标题】:delphi Send a file as byte array to a Rest servicedelphi 将文件作为字节数组发送到 Rest 服务
【发布时间】:2017-03-15 14:04:31
【问题描述】:

我正在使用 Delphi 10.1 Berlin

我想使用TRestRequest 将图像数据作为TBytes 发送到Rest 服务,但我找不到将TBytes 传递给TRestRequest.AddBody() 方法或任何其他方法的方法。

POST http://myserver:1111//Openxxx/RecxxxLxxxPxxxx HTTP/1.1 内容类型:文本/json 主机:我的服务器:1111 内容长度:28892 期望:100-继续 连接:保持活动 [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]

【问题讨论】:

标签: arrays rest delphi delphi-10.1-berlin


【解决方案1】:

TRESTRequest.AddBody() 具有接受 TStream 作为输入的重载。您可以使用 TBytesStream 类将您的 TBytes 包装到 TStream 中。

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;

【讨论】:

  • 我尝试了如下但没有改变。 codevar ABytes:TBytes; AStream:TBytesStream;开始 ABytes := TFile.ReadAllBytes('images.jpg'); AStream := TBytesStream.Create(ABytes); RESTRequest1.ClearBody; RESTRequest1.AddBody(AStream);// ByteArrayToString(ABytes)); RESTRequest1.执行;结束;code
  • 它会创建如下消息:
    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
  • 如果不深入研究 REST 客户端的源代码,我无法回答这个问题。但是,为什么要将文件读入 TBytes 包裹在 TStream 中,而不是直接使用 TFileStream 呢? var AStream: TFileStream; begin AStream := TFileStream.Create('images.jpg', fmOpenRead); RESTRequest1.ClearBody; RESTRequest1.AddBody(AStream); RESTRequest1.Execute; AStream.Free; end;
  • 嗨 Remmy 首先我要感谢您,但您的解决方案会创建一个空的 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
  • @RemyLebeau 如何使用 RESTRequest1.AddBody(... 如果有多个参数 rg。第一个参数是图像名称,第二个图像 blob 内存流?
【解决方案2】:

我已经解决了我的问题,如下所示:

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 2011-10-11
    相关资源
    最近更新 更多