kbmMW 5.0支持REST服务器的开发,并且非常简单,下面看看如何实作一个REST服务器。

首先我们制作一个服务器应用程序,增加一个简单的Form,并放置kbmMW组件。

在Delphi中单击File - New - VCL Forms Application

然后将以下kbmMW组件添加到Form中:

  • TkbmMWServer
  • TkbmMWTCPIPIndyServerTransport

将kbmMWTCPIPIndyServerTransport1的Server属性设置为kbmMWServer1。

双击kbmMWTCPIPIndyServerTransport1的Bindings属性,打开编辑器,添加0.0.0.0及绑定80端口,这是默认的HTTP服务器端口。您可以选择所需的任何其他端口来绑定,但请确保告知您的REST用户要访问的端口。

设置组件kbmMWTCPIPIndyTransport1的Streamformat属性为REST,如下图:

保存项目,Delphi将自动填加引用的单元,双击Form,建立OnCreate事件:

procedure TForm7.FormCreate(Sender: TObject);
begin
kbmMWServer1.AutoRegisterServices;
kbmMWServer1.Active:=true;
end;

定位到单元的interface段,手工填加引用的单元kbmMWRESTTransStream.
再次保存,得到如下的单元:

unit Unit7;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, kbmMWCustomTransport, kbmMWServer,
kbmMWTCPIPIndyServerTransport, kbmMWRESTTransStream; type
TForm7 = class(TForm)
kbmMWServer1: TkbmMWServer;
kbmMWTCPIPIndyServerTransport1: TkbmMWTCPIPIndyServerTransport;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; var
Form7: TForm7; implementation {$R *.dfm} procedure TForm7.FormCreate(Sender: TObject);
begin
kbmMWServer1.AutoRegisterServices;
kbmMWServer1.Active:=true;
end; end.

现在,一个实现REST服务器的基础功能具备了,接下来,我们来填加一些可以从任意REST客户端调用的具体功能.
在Delphi中,单击File-New-Other-Components4Developers wizard:

在继续选择我们要添加的kbmMW Service的类型之前,需要确定要创建什么类型的REST服务器。它可以是一个纯粹的REST服务器,只提供自己的代码中的数据,也可以是常规的Web服务器,可以从磁盘上的文件(如html模板,图像,CSS文件等)提供数据。

这里,我们只想做一个纯粹的REST服务器,所以选择了Smart service / kbmMW_1.0。

如果你希望能够从磁盘提供文件,甚至可以将代理请求提供给其他FastCGI兼容服务器(如PHP等),那么您将选择HTTP智能服务。

点击下一步,输入REST服务的默认名称,在这个例子中,我称之为MyREST。

接下来一路Next,直到下面显示的页面,然后点击绿色的勾号按钮

现在已经生成了没有功能的Service。表面看,这个Service就像一个TDataModule,可以放在TDataModule上的任意组件这里都可以用,但是现在我们对它的代码更感兴趣,所以按F12切换到代码视图,浏览顶部的注释,直到找到实际的代码。

type

[kbmMW_Service('name:MyREST, flags:[listed]')]
[kbmMW_Rest('path:/MyREST')]
// Access to the service can be limited using the [kbmMW_Auth..] attribute.
// [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')] TkbmMWCustomSmartService8 = class(TkbmMWCustomSmartService)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
// HelloWorld function callable from both a regular client,
// due to the optional [kbmMW_Method] attribute,
// and from a REST client due to the optional [kbmMW_Rest] attribute.
// The access path to the function from a REST client (like a browser)+
// is in this case relative to the services path.
// In this example: http://.../MyREST/helloworld
// Access to the function can be limited using the [kbmMW_Auth..] attribute.
// [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')]
[kbmMW_Rest('method:get, path:helloworld')]
[kbmMW_Method]
function HelloWorld:string;
end; implementation uses kbmMWExceptions; {$R *.dfm} // Service definitions.
//--------------------- function TkbmMWCustomSmartService8.HelloWorld:string;
begin
Result:='Hello world';
end;

如果您现在编译和运行应用程序,就得到了只有一个REST功能的Web服务器,这个功能叫HelloWorld,不带参数,并返回一个字符串。

打开你最喜欢的浏览器,并通过在地址栏中输入这个功能的地址来测试该功能:

http://localhost/MyREST/helloworld

确保地址的大小写是正确的,因为HTTP标准描述地址的URL部分必须区分大小写。如果你写的是http://localhost/MyREST/HelloWorld,你会被告知请求无效。

这看起来已经很好了,但我的REST客户端期望接收一个JSON对象,而不仅仅是简单的文本。

现在我准备展示三种方法来做到这一点:

  1. 手动方式
  2. 半自动化方式
  3. 全自动化的方式

1.手动方式,将HelloWorld函数更改为如下所示:

function TkbmMWCustomSmartService8.HelloWorld:string;
begin
Result:='{''result'':''Hello world''}';
end;

REST客户端将收到一个名为result的属性的匿名对象,其中包含“Hello world”。

2.半自动化方式:

uses kbmMWExceptions
,kbmMWObjectNotation
,kbmMWJSON; {$R *.dfm} // Service definitions.
//--------------------- function TkbmMWCustomSmartService8.HelloWorld:string;
var
o:TkbmMWONObject;
jsonstreamer:TkbmMWJSONStreamer;
begin
o:=TkbmMWONObject.Create;
jsonstreamer:=TkbmMWJSONStreamer.Create; o.AsString['result']:='Hello world';
Result:=jsonstreamer.SaveToUTF16String(o); jsonstreamer.Free;
o.Free;
end;

这样可以很容易地创建复杂的JSON文档,更爽的是,由于我们使用kbmMW的object notation framework,因此可以选择XML或YAML或BSON或MessagePack等格式进行传输。

3.全自动化方式:

type

TMyResult = class
private
FResult:string;
public
property Result:string read FResult write FResult;
end; [kbmMW_Service('name:MyREST, flags:[listed]')]
[kbmMW_Rest('path:/MyREST')]
// Access to the service can be limited using the [kbmMW_Auth..] attribute.
// [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')] TkbmMWCustomSmartService8 = class(TkbmMWCustomSmartService)
private
[kbmMW_Rest('method:get, path:helloworld, anonymousResult:true')]
[kbmMW_Method]
function HelloWorld:TMyResult;
end; implementation uses kbmMWExceptions; {$R *.dfm} // Service definitions.
//--------------------- function TkbmMWCustomSmartService8.HelloWorld:TMyResult;
begin
Result:=TMyResult.Create;
Result.Result:='Hello world';
end; initialization
TkbmMWRTTI.EnableRTTI(TkbmMWCustomSmartService8);
kbmMWRegisterKnownClasses([TMyResult]);
end.

全自动化方式简单的实现返回具有所需信息的对象,kbmMW自动将对象转换为JSON(因为我们正在使用REST streamformat)。

为了确保kbmMW知道对象类型,我们通过kbmMWRegisterKnownClasses进行注册。如果我们没有,kbmMW会抱怨它不知道该对象。

不要担心TMyResult实例会泄漏,当不再使用它时,kbmMW将自动释放它。如果你不希望通过kbmMW释放返回的对象,可以通过在HelloWorld方法的kbmMW_Rest属性中包含freeResult:false来进行说明。

还要注意,kbmMW_Rest属性设置现在包括:anonymousResult:true。这告诉kbmMW我们希望生成的JSON是匿名的,结果如下:

{“Result”:“Hello world”}
如果属性设置中不包括anonymousResult,则默认为true,即匿名输出json结果。
 
如果属性设置包括anonymousResult:false,结果将如下所示:
{“TMyResult”:{“Result”:“Hello world”}}

是否匿名输出json,没有对错,取决你的需要,但是一定要记得,输出结果是不同的。

有很多控制选项可以通过设置对象的各种属性来流式传输对象。例如可以选择要以不同的名称返回Result属性。

kbmMW还能返回TkbmMemTable实例,数组和许多其他类型的信息,因此几乎不用其他代码行就可以轻松地实现您的kbmMW业务功能。

作为最后的评论,由于HelloWorld方法也被标记为属性[kbmMW_Method],它也可以由kbmMW客户端调用。

你可以随意转发、评论、点赞、推荐这篇文章

REST easy with kbmMW #1的更多相关文章

  1. REST easy with kbmMW #3 – SSL

    我在前两篇文章中展示了“REST easy with kbmMW”文章,如何使用kbmMW制作REST服务器,以及如何使用该REST服务器轻松地从数据库返回和存储数据,所有这些都在不到30行的真实数据 ...

  2. REST easy with kbmMW #14 – DB Controlled login

    介绍 关于如何使用授权和登录管理来构建应用服务器还存在一些问题,其中之一就是用户及其角色如何在在数据库中定义.该文将解释使用TkbmMWAuthorizationManager解决此问题的一种方法.有 ...

  3. REST easy with kbmMW #15 – Handling HTTP POST

    我被问到有关如何通过基于kbmMW智能服务(Smart Service)的REST处理POST的问题. 这篇博客文章解释了典型的POST各种形式的访问,以及如何在kbmMW中处理它们. POST变种W ...

  4. REST easy with kbmMW #24 使用kbmMW实现JSON/XML/YAML转换成对象

    你想过没有,把一个给定的xml或json生成一个Delphi类,并通过这个类完成对xml或json的读写操作吗? 不管有没有,现在kbmMW为我们实现了,看下面这行代码: var s:string; ...

  5. REST easy with kbmMW #21 – Delphi client stubs

    在之前的博文中,我提到新的存根生成器框架具有生成Delphi客户端存根所需的功能,使得开发Delphi智能客户端非常容易,完全支持编译时的类型检查和IDE类/属性帮助. 我没想到会把它包含在即将发布的 ...

  6. REST easy with kbmMW #20 – OpenAPI and Swagger UI

    即将推出的kbmMW更新不仅是一些bug修正,同时将包含一个新的主要功能:客户端存根生成器框架. 那什么是客户端存根生成器框架呢? 他是一个基于kbmMW smart services,可以生成由各种 ...

  7. REST easy with kbmMW #17 – Database 6 – Existing databases

    kbmMW已经包含了非常精细的功能来确定和解释数据库中表的元数据. 在下一版本中,这个功能将得到进一步加强,可以导入现有数据库中的表,自动创建与表相匹配的ORM实体类. 这意味着你能够使用kbmMW的 ...

  8. REST easy with kbmMW #16 – Multiple servers using HTTP.sys transport

    前文写过使用HTTP.sys转输层(TkbmMWHTTPSysServerTransport),实现一个kbmMW应用服务器. 如果在一台服务器上,同时运行多个,基于TkbmMWHTTPSysServ ...

  9. REST easy with kbmMW #4 – Access management

    在前面有关如何使用kbmMW创建REST服务器的基础上,现在已经到了考虑该如何控制用户的访问.什么是访问管理?就是“允许谁做什么"的问题. 显然,这个世界中存在数据,应该保护他而不被未授权的 ...

随机推荐

  1. DPDK 网络加速在 NFV 中的应用

    目录 文章目录 目录 前文列表 传统内核协议栈的数据转发性能瓶颈是什么? DPDK DPDK 基本技术 DPDK 架构 DPDK 核心组件 应用 NUMA 亲和性技术减少跨 NUMA 内存访问 应用 ...

  2. MongoDB导入文件夹(内含json和bson文件)

    1. 使用mongo命令将数据库删除: mongo命令: use db_name; db.dropDatabase() 2. 导入(指定文件夹)数据: linux命令: mongorestore -d ...

  3. Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法

    时隔一个多月我又回来啦! 坚持真的是很难的一件事,其它事情稍忙,就很容易说服自己把写博客的计划给推迟了. 好在终于克服了自己的惰性,今天又开始了. 本篇继续我的Luaframework学习之路. 一. ...

  4. 网卡做bond 导致丢包

    值班中发现一台服务器报到网关丢包,带宽200M. 用  ethtool bond0 查看网卡带宽信息,发现 Speed 为 3100M ,非 1000 的整数倍或10000的整数倍,感觉不对,因为是做 ...

  5. hadoop第一个程序WordCount

    hadoop第一个程序WordCount package test; import org.apache.hadoop.mapreduce.Job; import java.io.IOExceptio ...

  6. fdisk中参数配置说明表

    命令 描述 a 设置活动分区标志 b 编辑BSD Unix系统用的磁盘标签 c 设置DOS兼容标志 d 删除分区 l 显示可用的分区类型 m 显示命令选项(帮助) n 添加一个新的分区 o 创建DOS ...

  7. 【VS开发】ConvertBSTRToString(filename) 不能将string转换为BSTR

    环境:win7,x64,vs2008 sp1 把VC 6.0的工程文件用VS2008打开,编译报错: error C2664:"_com_util::ConvertBSTRToString& ...

  8. C学习笔记-数组

    数组的概念 数组是一组具有相同数据类型的变量集合,这里要注意两点,数组只能存储相同的数据类型和数组的内存是连续的,这位数组和指针的联系奠定了基础. 一维数组 定义及初始化 一维数组指的是只有一个下标的 ...

  9. 微信扫码无法直接下载APP的apk的解决办法

    PHP的处理方式:http://blog.sina.com.cn/s/blog_4cd978f90102wx92.html

  10. selenium实现京东商城首页查找元素

    语言:Python 京东商城想要找到某个未加载出的元素,需要将页面加载出来. 使用js实现 流程: 1. 需要引入包: # 引入需要的包 import time from selenium impor ...