我们将使用 Delphi 中最现代、功能最强大的 Web 服务器框架:WebBroker。

什么是 WebBroker?
WebBroker 是 Delphi 自带的、用于创建 Web 应用程序的框架,它诞生于 CGI 时代,但现在已经演变得非常强大,可以创建 ISAPI/NSAPI 模块、Windows 服务以及独立的 HTTP 服务器,它的工作流程可以概括为:
- HTTP 服务器:接收来自浏览器的 HTTP 请求。
- 分发器:根据请求的 URL 路径,将请求分发给对应的 Web 模块。
- Web 模块:这是核心容器,它包含一个或多个页面生成器。
- 页面生成器:通常是一个
TWebActionItem,它根据请求执行特定逻辑,并生成响应内容(HTML、JSON、XML 等)。 - 响应:将生成的内容通过 HTTP 协议返回给浏览器。
第一步:创建项目
我们将创建一个独立的 HTTP 服务器,这样最简单,无需配置 IIS 或 Apache。
- 打开 Delphi (以 RAD Studio 11 Alexandria 为例,其他版本类似)。
- 选择 File -> New -> VCL Forms Application - Delphi。
- 在窗体上,从 Internet 选项卡中拖拽一个
THTTPApp组件到窗体上,这个组件是 WebBroker 应用的核心。 - 选中窗体上的
THTTPApp组件,在对象检查器中找到Dispatcher属性,点击其省略号 按钮。 - 这将打开 Web 调度编辑器,这是我们配置 URL 路由和响应逻辑的地方。
- 点击 Add 按钮,添加一个新的
TWebActionItem。- Name:
actHelloWorld - PathInfo:
/hello(这是用户需要访问的路径) - MethodType:
mtGET(表示这个路径只响应 GET 请求)
- Name:
- 双击
actHelloWorld,在代码编辑器中会自动生成actHelloWorldAction事件处理程序,这是我们的核心逻辑。
第二步:编写服务器端源码
我们将编写完整的代码,这包括主窗体、Web 调度逻辑以及一个简单的数据访问示例。
主窗体单元 (Unit1.pas)
这是程序的入口点,负责启动 Web 服务器。

unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdHTTPWebBrokerBridge, Web.HTTPApp;
type
TForm1 = class(TForm)
HTTPApp1: THTTPApp;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FServer: TIdHTTPWebBrokerBridge;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
WebModuleUnit1; // 引入我们的 Web 模块单元
procedure TForm1.FormCreate(Sender: TObject);
begin
FServer := TIdHTTPWebBrokerBridge.Create(Self);
FServer.DefaultPort := 8080; // 设置服务器监听端口
FServer.Active := True; // 启动服务器
ShowMessage('Web Server started on http://localhost:8080');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(FServer) then
begin
FServer.Active := False;
FServer.Free;
end;
end;
end.
Web 模块单元 (WebModuleUnit1.pas)
这是处理所有 Web 请求的核心模块,Delphi 在创建项目时通常会自动生成这个文件。
unit WebModuleUnit1;
interface
uses
System.SysUtils, System.Classes, Web.HTTPApp, Web.HTTPProd;
type
TWebModule1 = class(TWebModule)
WebDispatcher1: TWebDispatcher;
procedure WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
procedure WebModule1actHelloWorldAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
procedure WebModule1actUsersAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
WebModule1: TWebModule1;
implementation
{$R *.dfm}
uses
System.JSON; // 用于生成 JSON 响应
// 默认处理器,当访问的路径不存在时触发
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.Content := '<h1>Delphi Web Server</h1>' +
'<p>Welcome to the Delphi WebBroker server.</p>' +
'<p>Available endpoints:</p>' +
'<ul>' +
' <li><a href="/hello">/hello</a> - A simple HTML page.</li>' +
' <li><a href="/users">/users</a> - A JSON list of users.</li>' +
'</ul>';
end;
// 处理 /hello 路径
procedure TWebModule1.WebModule1actHelloWorldAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.ContentType := 'text/html';
Response.Content := '<!DOCTYPE html>' +
'<html>' +
'<head><title>Hello from Delphi!</title></head>' +
'<body>' +
' <h1>Hello, World!</h1>' +
' <p>This page was served by a Delphi WebBroker server.</p>' +
' <p>The current time is: ' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Now) + '</p>' +
'</body>' +
'</html>';
end;
// 处理 /users 路径,返回 JSON 数据
procedure TWebModule1.WebModule1actUsersAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
jsonList: TJSONArray;
jsonObj: TJSONObject;
i: Integer;
begin
// 创建一个 JSON 数组
jsonList := TJSONArray.Create;
// 模拟从数据库获取数据
for i := 1 to 5 do
begin
jsonObj := TJSONObject.Create;
jsonObj.AddPair('id', TJSONNumber.Create(i));
jsonObj.AddPair('name', TJSONString.Create('User ' + IntToStr(i)));
jsonObj.AddPair('email', TJSONString.Format('user%d@example.com', [i]));
jsonList.AddElement(jsonObj);
end;
// 设置响应内容类型为 JSON
Response.ContentType := 'application/json';
// 将 JSON 数组转换为字符串并设置为响应内容
Response.Content := jsonList.ToString;
// 释放 JSON 对象 (在实际应用中,你可能需要更复杂的生命周期管理)
jsonList.Free;
end;
end.
窗体文件 (Unit1.dfm)
这个文件是自动生成的,通常不需要修改。
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Delphi Web Server'
ClientHeight = 299
ClientWidth = 647
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object HTTPApp1: THTTPApp
Left = 48
Top = 24
end
end
第三步:运行和测试
-
按 F9 运行项目。
-
程序会弹出一个消息框:“Web Server started on http://localhost:8080”,并在后台启动服务器。
(图片来源网络,侵删) -
打开你的网页浏览器,访问以下地址:
-
http://localhost:8080你会看到默认的欢迎页面,列出了可用的 API 端点。 -
http://localhost:8080/hello你会看到一个动态生成的 HTML 页面,显示 "Hello, World!" 和当前服务器时间。 -
http://localhost:8080/users你会看到一个 JSON 格式的用户列表,这是典型的 API 响应。
-
第四步:进阶与扩展
这个简单的例子展示了 WebBroker 的基本功能,一个真实的 Web 服务器还需要更多功能:
集成数据库
要连接数据库(如 Firebird, MySQL, SQL Server, SQLite),你需要:
- 在
uses子句中添加数据库连接组件的单元,FireDAC.Comp.Client,FireDAC.Comp.DataSet。 - 在
TWebActionItem的事件处理程序中,创建TFDConnection,TFDQuery等组件。 - 执行 SQL 查询,并将结果集转换为 JSON。
示例代码片段 (在 actUsersAction 中):
// 在 uses 中加入 FireDAC 单元
// uses ..., FireDAC.Comp.Client, FireDAC.Comp.DataSet, FireDAC.Stan.Def;
// ... 在 actUsersAction 中 ...
var
jsonList: TJSONArray;
jsonObj: TJSONObject;
qry: TFDQuery;
begin
jsonList := TJSONArray.Create;
qry := TFDQuery.Create(nil);
try
qry.Connection := FDConnection1; // 假设你已经配置好了 FDConnection1
qry.SQL.Text := 'SELECT id, name, email FROM users';
qry.Open;
while not qry.Eof do
begin
jsonObj := TJSONObject.Create;
jsonObj.AddPair('id', TJSONNumber.Create(qry.FieldByName('id').AsInteger));
jsonObj.AddPair('name', TJSONString.Create(qry.FieldByName('name').AsString));
jsonObj.AddPair('email', TJSONString.Create(qry.FieldByName('email').AsString));
jsonList.AddElement(jsonObj);
qry.Next;
end;
finally
qry.Free;
end;
Response.ContentType := 'application/json';
Response.Content := jsonList.ToString;
jsonList.Free;
end;
使用 REST 格式 (更现代的 API)
现代 API 通常使用 RESTful 风格,URL 如 /api/users/123,你可以通过修改 TWebActionItem 的 PathInfo 来实现。
- PathInfo:
/api/users/*(星号是通配符) - 在事件处理程序中,你可以从
Request.PathInfo中获取123这个 ID。
procedure TWebModule1.WebModule1actUserDetailAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var userId: string; // ... 数据库查询逻辑 begin // 从 /api/users/123 中提取 ID userId := Request.PathInfo.Substring(11); // 跳过 "/api/users/" 部分 Response.Content := 'Fetching details for User ID: ' + userId; end;
静态文件服务
WebBroker 默认不提供静态文件(如 CSS, JS, 图片)服务,你需要自己实现一个处理程序来检查文件是否存在,如果存在就读取并返回。
procedure TWebModule1.WebModule1StaticFileAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
filePath: string;
fileStream: TFileStream;
begin
// 假设所有静态文件都在 "public" 文件夹下
filePath := ExtractFilePath(ParamStr(0)) + 'public' + Request.PathInfo;
if FileExists(filePath) then
begin
fileStream := TFileStream.Create(filePath, fmOpenRead or fmShareDenyNone);
try
Response.ContentType := GetMIMEType(filePath); // 需要一个函数来根据扩展名返回 MIME 类型
Response.ContentStream := fileStream;
fileStream := nil; // 转移所有权给 Response
finally
if Assigned(fileStream) then
fileStream.Free;
end;
end
else
begin
Response.StatusCode := 404; // Not Found
Response.Content := 'File not found.';
end;
Handled := True;
end;
部署
- 独立服务器: 你可以直接编译
.exe文件,在任何 Windows 机器上运行。 - Windows 服务: 将程序打包成 Windows 服务,可以实现开机自启,并在后台稳定运行。
- ISAPI/NSAPI 模块: 将程序编译成
.dll文件,部署在 IIS 或 Apache 上,这是高性能的部署方式。
这份 Delphi Web 服务器源码为你提供了一个坚实的基础,WebBroker 框架虽然看起来有些“传统”,但它非常稳定、高效,并且完全集成在 Delphi 生态中,通过它,你可以构建从简单的网页到复杂的 RESTful API 各种各样的 Web 应用,随着你对 Delphi 更深入的了解,你可以进一步探索 DataSnap(用于构建多层应用)和 MS-Graph(用于构建现代化的 Web 客户端应用)等更高级的主题。
