Raf*_*rth 2 pdf delphi rest client
我的应用程序使用"application/json"发送数据(个人信息).如果数据有效,则服务器通过"application/pdf"向我发回PDF文件.但是当RestResponse到达时,会弹出一个异常:"目标多字节代码页中不存在unicode字符的映射".我不知道发生了什么事.我在过去的4天里正在研究这个问题,我无法解决这个问题.异常弹出:"RRequest.Execute;".这是我的代码人:
procedure TThreadBoleto.Execute;
var
RCtx : TRttiContext;
RType : TRttiType;
RProp : TRttiProperty;
I : integer;
PDF : TFile;
begin
try
try
RClient := TRESTClient.Create('');
with RClient do begin
AcceptEncoding := 'identity';
FallbackCharsetEncoding := 'UTF-8';
Accept := 'application/json;text/plain;application/pdf;';
AcceptCharset := 'UTF-8';
BaseURL := 'https://sandbox.boletocloud.com/api/v1/boletos';
ContentType := 'application/x-www-form-urlencoded';
HandleRedirects := true;
RCtx := TRttiContext.Create;
RType := RCtx.GetType(THRBoleto.ClassType);
I := 0;
for RProp in RType.GetProperties do
begin
Params.AddItem;
Params.Items[I].name := LowerCase(RProp.Name.Replace('_','.'));
Params.Items[I].Value := RProp.GetValue(THRBoleto).AsString;
I := I + 1;
end;
end;
RRequest := TRESTRequest.Create(RRequest);
with RRequest do begin
Accept := 'application/json;text/plain;application/pdf;';
Client := RClient;
Method := rmPost;
SynchronizedEvents := false;
AcceptCharset := 'UTF-8';
end;
RResponse := TRESTResponse.Create(RResponse);
RResponse.ContentType := 'application/pdf;*/*;';
RResponse.ContentEncoding := 'UTF-8';
RAuth := THTTPBasicAuthenticator.Create('','');
with RAuth do begin
Username := 'anAPItokenAccess';
Password := 'token';
end;
RClient.Authenticator := RAuth;
RRequest.Response := RResponse;
RRequest.Execute;
PDF.WriteAllBytes(ExtractFilePath(Application.ExeName)+'boleto.pdf',RResponse.RawBytes);
OutputStrings.Add(RResponse.Content);
OutputStrings.Add('');
OutputStrings.Add('');
OutputStrings.AddStrings(RResponse.Headers);
except on E:Exception do
ShowMessage('Error: '+E.Message);
end;
finally
THRBoleto.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
你确定在RRequest.Execute()通话中发生了错误吗?您试图String在读取RResponse.Content属性时接收PDF数据,因此我希望在该调用上出现Unicode错误.PDF文件不是文本数据,它是二进制数据,因此接收它的唯一安全方法是使用RResponse.RawBytes属性.
此外,您根本不应该设置RResponse.ContentType或RResponse.ContentEncoding属性(更不用说您将它们设置为无效值).它们将根据收到的实际响应填写.
由于您RRequest.Accept要将属性设置为包含您愿意在响应中接受的3种不同媒体类型,因此您需要查看RResponse.ContentType属性值以确保在保存RawBytes到文件之前实际接收PDF .pdf文件.如果您收到文本或JSON响应,则无法将其作为PDF处理.
就个人而言,我发现REST组件非常错误.你可能有更好的运气使用Indy's TIdHTTP,例如:
uses
..., IdGlobal, IdGlobalProtocols, IdHTTP, IdSSLOpenSSL;
procedure TThreadBoleto.Execute;
var
RCtx : TRttiContext;
RType : TRttiType;
RProp : TRttiProperty;
Client: TIdHTTP;
Params: TStringList;
Response: TMemoryStream;
begin
Client := TIdHTTP.Create;
try
with Client.Request do begin
AcceptEncoding := 'identity';
Accept := 'application/json;text/plain;application/pdf';
AcceptCharset := 'UTF-8';
ContentType := 'application/x-www-form-urlencoded';
BasicAuthentication := True;
Username := 'anAPItokenAccess';
Password := 'token';
end;
Client.HandleRedirects := true;
RCtx := TRttiContext.Create;
RType := RCtx.GetType(THRBoleto.ClassType);
Response := TMemoryStream.Create;
try
Params := TStringList.Create;
try
for RProp in RType.GetProperties do
Params.Add(LowerCase(RProp.Name.Replace('_','.')) + '=' + RProp.GetValue(THRBoleto).AsString);
Client.Post('https://sandbox.boletocloud.com/api/v1/boletos', Params, Response);
finally
Params.Free;
end;
Response.Position := 0;
case PosInStrArray(ExtractHeaderMediaType(Client.Response.ContentType), ['application/pdf', 'application/json', 'text/plain'], False) of
0: begin
// save PDF
Response.SaveToFile(ExtractFilePath(Application.ExeName)+'boleto.pdf');
OutputStrings.Add('[PDF file]');
end;
1: begin
// process JSON as needed
OutputStrings.Add(ReadStringAsCharset(Response, Client.Response.Charset));
end;
2: begin
// process Text as needed
OutputStrings.Add(ReadStringAsCharset(Response, Client.Response.Charset));
end;
else
// something else!
OutputStrings.Add('[Unexpected!]');
end;
finally
Response.Free;
end;
OutputStrings.Add('');
OutputStrings.Add('');
OutputStrings.AddStrings(Client.Response.RawHeaders);
finally
Client.Free;
end;
end;
procedure TThreadBoleto.DoTerminate;
begin
if FatalException <> nil then
begin
// Note: ShowMessage() is NOT thread-safe!
ShowMessage('Error: ' + Exception(FatalException).Message);
end;
THRBoleto.Free;
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
698 次 |
| 最近记录: |