摘要:本文通过一个实例详细介绍了Web应用
程序的原理,利用C++Builder开发Web应用程序的过程。
Web应用程序是运行在服务器端的可执行程序或动态连接库。它们可以响应用户要求,动态产生超文本页面,并将信息提供给客户浏览器。
一般来说,Web应用程序可分为五种类型,分别是ISAPI、NSAPI、CGI、WinCGI、Activex。这五种不同的方式都有各自的限制,也就是说,这些方式将会限制Web服务器和前端浏览器的类型。如下表所示:
由于上述Web应有程序的标准定义并不相同,程序的写法各异,这 样就给开发者造成不小的困挠,因为你不太可能了解每一种标准的写法。而C++Builder可以很好地解决这个问题。C++Builder将Web应有程 序的做法封装成组件,让开发者面对的是一致的开发界面,一致的开发原理,唯一不同的地方在于开始产生程序时所选择的程序结构,至于程序的编写细节和方式都 一模一样。
创建一个简单的Web应用程序
首先,点击C++Builder IDE 菜单File | New option 选中 Web Server Application 图标 (见图 1).
图1
接下来,我们有如图2所示三种选择:
图2
CGI (Common Gateway Interface)运行时需要一个独立的进程,而ISAPI/NSAPI动态连接库运行时则映射到Web服务器进程中,比CGI需要较少的资源。 ISAPI/NSAPI动态连接库的这个特点也造成了调试时的不方便,因此较好的办法是先创建一个CGI程序,调试它,然后再把它转化成ISAPI /NSAPI动态连接库。所以在这里我们选择"CGI Stand-alone executable"。
这样,我们就得到了一个TWebModule 对象, 如图3:
图3 空白的Web模块
我们下面讨论一下Web应用程序是如何工作的。Web应用程序实际上是Web服务器在功能上的扩展,就好像Windows应用程序是Windows在功 能上的扩展一样。当Web应用程序从Web服务器检索到一个HTTP请求消息时,就对HTTP请求消息进行分析,生成HTML页面传递给Web服务器,再 由Web服务器传递给客户。
C++Builder Web应用 程序的 一个关键部件是Web Module ,它收集和管理着一组动作项(TwebActionItem对象),用TwebRequest对象来描述HTTP请求消息,并根据HTTP请求消息来指派 其中一个动作去响应客户的请求,实际上就是填写TWebResponse对象的Content特性。如图4所示:
图4:Web应用程序的逻辑机构
由此可见,一个Web应用程序应当创建若干个动作项,以供Web调度器(TwebDispatcher)指派。C++Builder 是用一个专门的动作项编辑器来创建和管理动作项的。
右键单击Web模块,在弹出的菜单中选择"Action Editor"命令。然后添加一个动作项,通过它的PathInfo属性可以设置动作项在Web服务器上的入口路径,而default属性设置当PathInfo属性为空时该动作项是否执行。如图5:
图 5: 动作项编辑器
现在,我们可以为动作项编写代码了:
可 以看出,在处理动作项的OnAction事件的句柄中,可以通过Request参数来访问客户的请求消息。不过,这里只关心Response参数。要相应 客户的请求,实际上就是把用HTML描述的页面赋值给Response的Content属性,Web调度器会自动把相应结果传递给Web服务器,再由 Web服务器传递给客户。
至此,一个简单的Web应用程序创建完毕,现在通过Web浏览器测试它。要注意的是Web应用程序所在路径应有可执行权限。
图6: 一个动态页面的示例
创建一个用于处理用户输入的Web应用程序
让我们在上面例子的基础上继续创建一个用于处理用户输入的Web程序。
再添加一个动作项如图7所示:
图7: 再增加一个 TWebActionItem
在WebModule1放TPageProducer 对象,用它利用事先准备好的HTML模板生成HTML文档。如图8所示:
图8: 添加 TpageProducer到 WebModule1.
可以利用Microsoft FrontPage 做一个如图9的用户输入表:
图9: 用 Microsoft FrontPage. 做一个用户输入表
图9的HTML代码如下:
把上面的代码拷贝到TPageProducer 的HTMLDoc 属性编辑器中。
现在可以为TWebActionItem2的OnAction 事件写代码了:
编译好后,在浏览器中测试如图10:
图10: 利用Web应用程序生成的用户表单
接着,我们处理用户输入,把用户输入写入一个新的HTML页面。这就需要再增加一个TpageProducer组件。如图11:
图11: 添加 PageProducer2 用于处理用户输入页面
把以下代码添加到 HTMLDoc 属性中:
上面代码是一个HTML模板,它包括二个特殊的标识<#T1> 和<#T2>,同时它们也是用户输入表中两个编辑域的名称,在产生的HTML页面中将被用户数据所代替。这就需要处理PageProducer2的 OnHTMLTag事件。
继续增加一个动作项 TwebActionItem WebActionItem3 ,其PathInfo="/t3", OnAction 事件代码如下:
当用户按下Submit后,PageProducer2 获得相应呢?修改PageProducer1 的HTMLDoc 属性如下:
编译后测试,填写完表单后按下Submit按钮,结果如下:.
图12: 处理用户输入后的结果
以上仅仅是用C++Builder编写Web应用程序的开始,但已经有了很好的思路,相信大家可以在此基础上做更深入地研究,编写出更好的程序。
Web应用程序是运行在服务器端的可执行程序或动态连接库。它们可以响应用户要求,动态产生超文本页面,并将信息提供给客户浏览器。
一般来说,Web应用程序可分为五种类型,分别是ISAPI、NSAPI、CGI、WinCGI、Activex。这五种不同的方式都有各自的限制,也就是说,这些方式将会限制Web服务器和前端浏览器的类型。如下表所示:
Web应用程序 | 后端操作系统 | Web服务器 | 前端浏览器 |
ISAPI | Window NT | MS-IIS | 无限制 |
NSAPI | 无限制 | Nescape Server | 无限制 |
CGI | 无限制 | 无限制 | 无限制 |
WinCGI | Window3.1 | 16位Web服务器 | 无限制 |
Activex | Window NT | MS-IIS | MS-IE |
由于上述Web应有程序的标准定义并不相同,程序的写法各异,这 样就给开发者造成不小的困挠,因为你不太可能了解每一种标准的写法。而C++Builder可以很好地解决这个问题。C++Builder将Web应有程 序的做法封装成组件,让开发者面对的是一致的开发界面,一致的开发原理,唯一不同的地方在于开始产生程序时所选择的程序结构,至于程序的编写细节和方式都 一模一样。
创建一个简单的Web应用程序
首先,点击C++Builder IDE 菜单File | New option 选中 Web Server Application 图标 (见图 1).
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image001.gif)
图1
接下来,我们有如图2所示三种选择:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image003.jpg)
图2
CGI (Common Gateway Interface)运行时需要一个独立的进程,而ISAPI/NSAPI动态连接库运行时则映射到Web服务器进程中,比CGI需要较少的资源。 ISAPI/NSAPI动态连接库的这个特点也造成了调试时的不方便,因此较好的办法是先创建一个CGI程序,调试它,然后再把它转化成ISAPI /NSAPI动态连接库。所以在这里我们选择"CGI Stand-alone executable"。
这样,我们就得到了一个TWebModule 对象, 如图3:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image005.jpg)
图3 空白的Web模块
我们下面讨论一下Web应用程序是如何工作的。Web应用程序实际上是Web服务器在功能上的扩展,就好像Windows应用程序是Windows在功 能上的扩展一样。当Web应用程序从Web服务器检索到一个HTTP请求消息时,就对HTTP请求消息进行分析,生成HTML页面传递给Web服务器,再 由Web服务器传递给客户。
C++Builder Web应用 程序的 一个关键部件是Web Module ,它收集和管理着一组动作项(TwebActionItem对象),用TwebRequest对象来描述HTTP请求消息,并根据HTTP请求消息来指派 其中一个动作去响应客户的请求,实际上就是填写TWebResponse对象的Content特性。如图4所示:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image007.jpg)
图4:Web应用程序的逻辑机构
由此可见,一个Web应用程序应当创建若干个动作项,以供Web调度器(TwebDispatcher)指派。C++Builder 是用一个专门的动作项编辑器来创建和管理动作项的。
右键单击Web模块,在弹出的菜单中选择"Action Editor"命令。然后添加一个动作项,通过它的PathInfo属性可以设置动作项在Web服务器上的入口路径,而default属性设置当PathInfo属性为空时该动作项是否执行。如图5:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image008.gif)
图 5: 动作项编辑器
现在,我们可以为动作项编写代码了:
void __fastcall TWebModule1::WebModule1WebActionItem1Action( TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool &Handled) { AnsiString cont = AnsiString("<HTML><BODY><H3>Hello!</H3>"); cont = cont + AnsiString("<BR>"); cont = cont + AnsiString("<H2>Now is ") + TimeToStr(Time()) + AnsiString(" </H2>"); cont = cont + AnsiString("</BODY></HTML>"); Response->Content = cont; } |
可 以看出,在处理动作项的OnAction事件的句柄中,可以通过Request参数来访问客户的请求消息。不过,这里只关心Response参数。要相应 客户的请求,实际上就是把用HTML描述的页面赋值给Response的Content属性,Web调度器会自动把相应结果传递给Web服务器,再由 Web服务器传递给客户。
至此,一个简单的Web应用程序创建完毕,现在通过Web浏览器测试它。要注意的是Web应用程序所在路径应有可执行权限。
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image010.jpg)
图6: 一个动态页面的示例
创建一个用于处理用户输入的Web应用程序
让我们在上面例子的基础上继续创建一个用于处理用户输入的Web程序。
再添加一个动作项如图7所示:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image011.gif)
图7: 再增加一个 TWebActionItem
在WebModule1放TPageProducer 对象,用它利用事先准备好的HTML模板生成HTML文档。如图8所示:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image013.jpg)
图8: 添加 TpageProducer到 WebModule1.
可以利用Microsoft FrontPage 做一个如图9的用户输入表:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image014.gif)
图9: 用 Microsoft FrontPage. 做一个用户输入表
图9的HTML代码如下:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <meta name="GENERATOR" content="Microsoft FrontPage 2.0"> <title>Untitled Normal Page</title></head> <body bgcolor="#FFFFFF"> <p> </p> <form method="GET"> <p>What is Your name?<font size="4"> <input type="text" size="20" name="T1"></font></p> <p>What is Your e-mail?<font size="4"> <input type="text" size="20" name="T2"></font></p> <p><font size="4"><input type="submit" name="B1" value="Submit"><input type="reset" name="B2" value="Reset"></font></p> </form> </body> </html> |
把上面的代码拷贝到TPageProducer 的HTMLDoc 属性编辑器中。
现在可以为TWebActionItem2的OnAction 事件写代码了:
void __fastcall TWebModule1::WebModule1WebActionItem2Action( TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool &Handled) { Response->Content=PageProducer1->Content(); } |
编译好后,在浏览器中测试如图10:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image016.jpg)
图10: 利用Web应用程序生成的用户表单
接着,我们处理用户输入,把用户输入写入一个新的HTML页面。这就需要再增加一个TpageProducer组件。如图11:
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image018.jpg)
图11: 添加 PageProducer2 用于处理用户输入页面
把以下代码添加到 HTMLDoc 属性中:
<html> <head> <title>Thank You!</title> </head> <body > <p>您好 <#T1>!</p> <p>感谢你添写了我们的调查表单,你的email地址为 <#T2>,以后我们会与你联系 !</p> </body> </html> |
上面代码是一个HTML模板,它包括二个特殊的标识<#T1> 和<#T2>,同时它们也是用户输入表中两个编辑域的名称,在产生的HTML页面中将被用户数据所代替。这就需要处理PageProducer2的 OnHTMLTag事件。
void __fastcall TWebModule1::PageProducer2HTMLTag( TObject *Sender, TTag Tag, const AnsiString TagString, TStrings *TagParams, AnsiString &ReplaceText) { ReplaceText = Request->QueryFields->Values[TagString] + Request->ContentFields->Values[TagString]; } |
继续增加一个动作项 TwebActionItem WebActionItem3 ,其PathInfo="/t3", OnAction 事件代码如下:
void __fastcall TWebModule1::WebModule1WebActionItem3Action( TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool &Handled) { Response->Content=PageProducer2->Content(); } |
当用户按下Submit后,PageProducer2 获得相应呢?修改PageProducer1 的HTMLDoc 属性如下:
<form method="POST" action="http://sopdrilling.com.cn/bcbtest/project1.exe/t3"> |
编译后测试,填写完表单后按下Submit按钮,结果如下:.
![](http://www.yesky.com/SoftChannel/72342371928834048/20010903/jt-2001-9-3-image020.jpg)
图12: 处理用户输入后的结果
以上仅仅是用C++Builder编写Web应用程序的开始,但已经有了很好的思路,相信大家可以在此基础上做更深入地研究,编写出更好的程序。