Web数据库服务系统包括一个Web浏览器作为用户界面,一个数据库服务器用作信息存储和数据采集,一个连接两者的Web应用服务器,Web应用软件出色地将数据陈述标准化,DBMS则组织和标准化数据库的接收与存储,Web浏览器通过TCP/IP与Web服务器相连,将页面请求与输入的数据发送给Web服务器,Web应用服务器把来自Web浏览器的请求转化为数据库服务器能接受的形式(SQL),传给数据库服务器,然后数据库服务器在数据库中进行相应的操作(插入、查询等),并把结果送回服务器扩展程序,数据库可以是应用服务器本地数据库,也可以是某个数据库服务器上的数据库。通过ODBC、BDE与Web服务器接口,最后,Web服务器程序将结果转化成Web浏览器能够接受的形式(如HTML文件),并发送回Web浏览器。在这样一个Web数据库服务系统中,用户只要在机器上安装了Web浏览器(如IE),就可通过Web页上显示的表格与数据库进行交互操作。

    Web数据库服务系统如图1所示:

 

图1

    创建Web服务器程序的具体步骤如下:

    第一步 Delphi的客户机/服务器版本已经包括了Web服务器端开发的框架:在object repository的第一页(NEW)上,选择Web Server Application图标,随后出现的对话框会为用户提供三个选项,ISAPI、CGI、WinCGI,如图2所示:

 

图2

    选取第一个,Delphi将为我们生成一个ISAPI应用程序的的基本结构。服务应用程序基于TWebmodule类,它派生自TWebDispatcher(此类定义了Request、Response属性,这两个属性存储了客户请求与将要发回用户端的响应),它是用来控制整个程序正确执行的,包含在其中的Action items用来获取有关用户请求信息,根据请求的路径名定义一系列行为(存储在Action数组属性中),这样,应用程序就可以轻松地响应不同路径名的请求,为每个可能的路径名调用不同的onAction事件处理程序,也就是说首先定义对应各种行为的路径名,然后定义对应着这些路径名的onAction事件处理程序。
第二步 编写事件处理程序时,将相应数据库操作加进去,Delphi提供了许多Internet与数据库操作组件,如TPageproducer、TQuerytableproducer、TDatasetpageprodure等,用这些组件可以方便地根据Request(用户请求),将查询信息转换为数据库查询命令传给数据库服务器,再将返回的数据库查询结果变成HTML页返回给用户,还可以将组件稍加修改,将接收到的Request作为数据源对服务器提供的数据库进行数据输入。另外在Webmodule中加入一个Session部件,并对其进行属性设置,用于数据库有多个链接时的管理,Session部件可以对程序中同时运行的多个实例进行完善的管理。下面以具体例子说明:

    例:下面一例是一个简便的通讯录管理,将通讯录表在Web上发布,用户也可以从浏览器将自己的地址输入到通讯录中。此例中有三个路径名,相应有三个onAction事件处理,二个查询,一个输入,如图3所示。

 

图3

    dllparse 数据库输入程序。dllquery 将数据库满足固定查询条件的数据发给浏览器的程序。dllshow 接收用户的查询条件,然后将满足条件的数据发给浏览器的程序。在Webmodule中,加入了Table、Query、Database、Session、PageProducer、Query

TableProducer、DataSetPageProduce,如图4所示。

delphi Sesson 系统服务程序 delphi web服务器_数据

 

图4

    处理程序的编码如下:

unit Web1;
    interface
    uses
    Windows, Messages, SysUtils, Classes, HTTPApp, DSProd, DBWeb, DBTables, Db;
    type
    TWebModule1 = class(TWebModule)
    Table1: TTable;
    Query1: TQuery;
    Database1: TDatabase;
    Session1: TSession;
    PageProducer1: TPageProducer;
    QueryTableProducer1: TQueryTableProducer;
    DataSetPageProducer1: TDataSetPageProducer;
    procedure PageProducer1HTMLTag(Sender: TObject; Tag: TTag;const TagString: String; TagParams: TStrings;var ReplaceText: String);
    procedure WebModule1dllparseAction(Sender: TObject;
    Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
    procedure WebModule1dllqueryAction(Sender: TObject;
    Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
    procedure WebModule1dllshowAction(Sender: TObject;
    Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
    private
    { Private declarations }
    public
    { Public declarations }
    end;
    var
    WebModule1: TWebModule1;
    implementation
    {$R *.DFM}
    {在TPageproducer中加入数据库输入功能,并返回给浏览器输入是否成功的标志页}
     procedure
    TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag;const TagString: String; TagParams: TStrings; var ReplaceText: String);
    var
     data:tstrings;
     i:integer;
    begin
     data:=nil;
     with request do
    begin
    case methodtype of
    mtpost:data:=contentfields;
    mtget:data:=queryfields;
    end;
    replacetext:=data.Values[tagstring];
    {将数据库表打开,把浏览器传来的数据分别赋给表的各个字段,再将数据写入数据库。}
    table1.Open;
    try
    table1.append;
    for i:=0 to table1.fieldcount-1 do table1.fields[i.value:=data.values[table1.fields[i].fieldname];
    table1.post;
    except //意外处理,处理数据库主键唯一性//
     raise exception.create(‘输入错误(姓名重复)');
    end;
    table1.close;
     end;
    end;
    procedure
    TWebModule1.WebModule1dllparseAction(Sender: TObject;Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
    begin
    response.content:=pageproducer1.Content ;
    end;
    {根据在 QUERY 定义的查询,用 QueryTableProducer 从数据库获取符合条件的数据,生成HTML页发给用户。}
    procedure
    TWebModule1.WebModule1dllqueryAction(Sender: TObject;Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
    begin
    with querytableproducer1 do begin
    header.add(‘<html>') ;
    header.add(‘<body>');
    footer.add(‘</body>');
    footer.add(‘</html>');
    query:=query1;
    query1.open;
    response.content:= querytableproducer1.Content ;
    query.Close;
    end;
    end;
    {从Request中得到用户要查询的name,将符合条件的记录用DataSetPageproducer组件生成HTML文件发给浏览器}
    procedure
    TWebModule1.WebModule1dllshowAction(Sender: TObject;Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
     var
    data1:tstrings;
    aa:string;
    i:integer;
    begin
    data1:=nil;
    with request do
     begin
     case methodtype of
     mtpost:data1:=contentfields;
     mtget:data1:=queryfields;
    end;
    end;
    aa:=data1.values[‘name'];
    for i:=length(aa)+1 to 10 do
    aa:=aa+‘ ';
    query1.params[0].asstring:=aa;
    query1.open;
    response.content:=datasetpageproducer1.content;
    query1.close;
    end;
    end.

    第三步 将编好的程序编译成DLL文件,在支持程序的服务器上调试,在HTML中调用。编程过程中需要注意的是:

    1. 在Webmodule中加入Session组件,以保证程序能支持数据库的多个链、支持多个浏览器的同时访问同一数据库的同一个表。

    2. 在定义Database时,注意将数据库登录提示log prompt设为n, keep inactiveconnection 设为n,以免用户在浏览器访问数据库时不能登录。