• REST easy with kbmMW #15 – Handling HTTP POST


    我被问到有关如何通过基于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:=0 to mp.Count-1 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('.
    eceivedfiles');
                 sFileName:='.
    eceivedfiles'+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/

  • 相关阅读:
    浅谈JavaScript中this指向的⼏种情况
    JavaScript、html简单的级联操作。
    异常处理中throws和throw的区别?
    java异常处理try-catch-finally的执行过程?
    什么是内连接、外连接、交叉连接(笛卡尔积)?
    主键和外键的区别
    集合和数组的比较(为什么要引入集合)?
    Java中对比单继承与多继承的优劣,以及java的解决方案
    数据库
    数据库集中控制的优势
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/9277927.html
Copyright © 2020-2023  润新知