REST easy with kbmMW #15 – Handling HTTP POST-LMLPHP

我被问到有关如何通过基于kbmMW智能服务(Smart Service)的REST处理POST的问题。

这篇博客文章解释了典型的POST各种形式的访问,以及如何在kbmMW中处理它们。

POST变种
Web/REST客户端可以通过多种方式POST数据:

1.作为URL的路径部分中的值数据
    例如:POST http://localhost/myservice/myfunction/10/20
2.作为URL的查询部分中的键/值数据
    例如:POST http://localhost/myservice/myfunction?arg1=10&arg2=20
3.作为body中的FORM键/值数据。
    例如:POST http://localhost/myservice/myfunction
    然后Body包含:
    name1=value1&name2=value2
4.作为body中的XML或JSON数据。
   例如: POST http://localhost/myservice/myfunction
   然后body包含:
   {“name1″:”value1″,”name2″:”value2”}
5.作为Multipart body 通常作为文件上传的一部分。
您可以根据客户端选择发送数据的方式,然后在服务端以不同方式提取数据。

第一种情况:

[kbmMW_Rest('method:post, path: "myfunction/{value1}/{value2}"')]
function MyFunction(
[kbmMW_Rest('value:"{value1}"')] AValue1:integer;
[kbmMW_Rest('value:"{value2}"')] AValue2:integer):string;

第二种情况:

[kbmMW_Rest('method:post, path: "myfunction"')]
function MyFunction(
[kbmMW_Rest('value:"$value1"')] AValue1:integer;
[kbmMW_Rest('value:"$value2"')] AValue2:integer):string;

第三种情况:

[kbmMW_Rest('method:post, path: "myfunction"')]
function MyFunction(
[kbmMW_Rest('value:body')] ABody:string):string;

然后MyFunctions这样实现:

var
qv:TkbmMWHTTPQueryValues; // Found in kbmMWHTTPUtils.pas
begin
qv:=TkbmMWHTTPQueryValues.Create;
try
qv.AsString:=ABody; // If the body is URL encoded you can use qv.AsEncodedString:=ABody
value1:=qv.ValueByName['value1'];
value2:=qv.ValueByName['value2'];
finally
qv.Free;
end;
end;

第四种情况,有多种方法:

1.如果数据是已知的,可以定义一个class来接收数据。

  [kbmMW_Root('data',[mwrfIncludeOnlyTagged])]
TData = class
private
FValue1:string;
FValue2:string;
public
[kbmMW_Attribute('name1')]
property Value1:string read FValue1 write FValue1; [kbmMW_Attribute('name2')]
property Value2:string read FValue2 write FValue2;
end;
...
[kbmMW_Rest('method:post, path: "myfunction"')]
function MyFunction([kbmMW_Rest('value: "body"')]const AData:TData):integer;

然后将向函数MyFunction提供一个AData实例,并在退出MyFunction时自动释放。

2.如果数据是未知的,则可以用XML或者JSON流

var
on:TkbmMWONCustomObject;
begin
json:=TkbmMWJSONStreamer.Create;
try
on:=json.LoadFromUTF16String(ABody);
if on.IsObject then
begin
value1:=TkbmMWONObject(on).AsString['name1'];
value2:=TkbmMWONObject(on).AsString['name2'];
end;
finally
json.Free;
end;
end;

第五种情况:

它处理起来有点复杂,但kbmMW包含一个TkbmMWHTTPMultiParts类,可用于解密multipart data中每一个边界所包含的数据。这次我们首先要弄清楚它实际上是否是一个multipart body。 然后我们需要弄清楚每个部分之间的边界标识符(boundary identification)是什么,然后我们可以开始将其拆分并分别处理每个部分。

[kbmMW_Rest('method:post, path: "myfunction"')]
function MyFunction:string; function TMyService.MyFunction:string;
var
i:integer;
mp:TkbmMWHTTPMultiParts;
p:TkbmMWHTTPMultiPart;
f:TkbmMWHTTPMimeHeaderValueFields;
helper:TkbmMWHTTPTransportStreamHelper;
sFileName,
sBoundary:string;
fs:TFileStream;
begin
Result:='No data found'; // First pick out content-type header field.
helper:=TkbmMWHTTPTransportStreamHelper(RequestTransportStream.Helper);
f:=helper.Header.ValueFields['Content-Type'];
if f=nil then
exit; // Check if boundary given. If so parse multiparts.
sBoundary:=f.ValueByName['boundary'];
if sBoundary<>'' then
begin
mp:=TkbmMWHTTPMultiParts.Create(RequestStream,sBoundary);
try
// Loop thru parts.
for i:= to mp.Count- do
begin
// Check if file upload.
p:=mp.Parts[i];
f:=p.Headers.ValueFields['Content-Disposition'];
sFileName:=f.ValueByName['filename'];
if sFileName<>'' then
begin
ForceDirectories('.\receivedfiles');
sFileName:='.\receivedfiles\'+sFileName;
DeleteFile(sFileName);
fs:=TFileStream.Create(sFileName,fmCreate+fmOpenWrite);
try
p.SaveToStream(fs);
finally
fs.Free;
end;
Result:='Thank you for the file '+sFileName;
end;
end;
finally
mp.Free;
end;
end;
end;

结束语

kbmMW REST smart service还有许多其他功能。 其中一些在“REST easy”系列的其他博客文章中有解释,您可能还想查看包含600多页文档,请访问我们的网站http://www.components4developers.com,寻找kbmMW文档。

如果你喜欢这篇文章,可以在任何地方分享关于kbmMW的消息,如分享和复制这个博客的内容或者联接到你认为任何可能有用的地方。

哦......还有关于那个特色图片的什么? 这是丹麦的邮箱...在丹麦语中我们称之为“Post kasser”。 因为互联网的作用,这种景观已经越来越少,过去10年里,约85%的邮局已经消失,相反,由当地的杂货店来处理各种慢如蜗牛的邮件。

原文地址:https://components4developers.blog/2018/07/07/rest-easy-with-kbmmw-15-handling-http-post/

05-11 17:43