一、创建web server application - c++builder
选择文件-新建-web server application - c++builder即可。中间一步步选择standlone GUI app、windows、vcl即可。因为我是部署在 windows server上的,并使用C++builder,delphi是一样的。
然后创建了project文件,但是要注意主程序Project.cpp中有一些错误,也是奇怪,自动创建的还有问题。
//---------------------------------------------------------------------------
#include <vcl.h>
#ifdef _WIN32
#include <tchar.h>
#endif
#pragma hdrstop
#include <Web.WebReq.hpp>
USEFORM("FormUnit1.cpp", Form1);
USEFORM("WebModuleUnit1.cpp", WebModule1); /* TWebModule: File Type */
//---------------------------------------------------------------------------
#ifdef USEPACKAGES
#pragma link "IndySystem.bpi"
#pragma link "IndyCore.bpi"
#pragma link "IndyProtocols.bpi"
#else
#pragma comment(lib, "IndySystem")
#pragma comment(lib, "IndyCore")
#pragma comment(lib, "IndyProtocols")
#endif
#pragma link "IdHTTPWebBrokerBridge"
//---------------------------------------------------------------------------
UUSEFORM("FormUnit1.cpp", Form1);
//---------------------------------------------------------------------------
xtern PACKAGE TComponentClass WebModuleClass;
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
if (WebRequestHandler() != NULL)
{
WebRequestHandler()->WebModuleClass = WebModuleClass;
}
Application->Initialize();
AApplication->CreateForm(__classid(TForm1), &Form1);
pplication->Run();
}
catch (Exception &exception)
{
Sysutils::ShowException(&exception, System::ExceptAddr());
}
return 0;
}
//------------------------------------------
Error1:UUSEFORM("FormUnit1.cpp", Form1); UUSEFORM去掉前面的U。
Error2: xtern PACKAGE TComponentClass WebModuleClass; 前面掉了一个e
Error3: AApplication->CreateForm(__classid(TForm1), &Form1);
pplication->Run(); 前面的Application多了一个A, 后面的pplication少了一个A。
纠正以后就可以运行了。出现独立的web server界面,如图1所示,这个就是Application。

图1
二、代码解释

图2
USEFORM("FormUnit1.cpp", Form1);
USEFORM("WebModuleUnit1.cpp", WebModule1); /* TWebModule: File Type */
这两个宏用于告诉 C++Builder IDE 如何创建和初始化表单。USEFORM 宏将 FormUnit1.cpp 和 WebModuleUnit1.cpp 中定义的类与它们对应的文件关联起来。
extern PACKAGE TComponentClass WebModuleClass;
声明一个外部的 WebModuleClass,这个类是由 WebModuleUnit1.cpp 中的 TWebModule 派生类提供的。
{
try
{
if (WebRequestHandler() != NULL)
{
WebRequestHandler()->WebModuleClass = WebModuleClass;
}
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Sysutils::ShowException(&exception, System::ExceptAddr());
}
return 0;
}
在 try 块中,程序首先检查 WebRequestHandler() 是否不为 NULL,如果不为 NULL,则设置其 WebModuleClass 为之前声明的 WebModuleClass。然后初始化应用程序,创建 Form1 表单,并运行应用程序。如果在运行过程中发生异常,catch 块会捕获异常并显示异常信息。
这段代码是 C++Builder Web 服务器应用程序的标准模板,它设置了应用程序的启动参数,初始化了 VCL 组件,创建了主表单,并启动了 Web 服务器模块。
三、添加Action Item
在web模块单元中webModuleUnite1的表单,就可以创建action item,默认是Defaulthandler。

因此实现了:WebModule1DefaultHandlerAction方法。
void __fastcall TWebModule1::WebModule1DefaultHandlerAction(TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool &Handled)
其中,TWebRequest *Request, TWebResponse *Response 这个两个参数属于Web Application的,它们和Action Item进行交互。如上图2所示。
1、添加Action
直接点击editing WebModule1 Action窗口上左上角Add New的创建Action,自动命名为WebActionItem1。,为了区别不同的动作,必须为每一个动作起一个名字,我们可以修改这个名字使之更有意义些。点击对话框中的动作名,ObjectInspector将会显示相应的属性。其中的MethodType用来指定对何种方法的请求消息作出响应,可供选择的项目有mtAny、mtGet、mtHead、mtPost和mtPut。其中后四项分别对应请求消息的方法GET、HEAD、POST和PUT,若你想要对所有的方法都作出响应,则可选择mtAny。

通过MethodType选择相应的动作,Pathinfo是路径信息,Event中的OnEvent产生下面的方法,当然是webmoduleunit1.cpp中。
void __fastcall TWebModule1::WebModule1WebActionItem1Action(TObject *Sender, TWebRequest *Request,
TWebResponse *Response, bool &Handled)
{
}
//---------------------------------------------------------------------------
其中最重要的是两个调用参数Request和Response。Request是一个TWebRequest对象,这种对象具有Accept,Authorization,CacheControl,Connection,...等属性,这些属性对应于HTTP请求消息中消息头的各个字段,这些属性的值就是这些字段的值。当上述响应过程被调用时,根据web服务器传送过来的消息头及消息实体,设置好对象Request的各个属性值,然后作为调用参数传递给执行动作的过程。对于查询消息,表示查询目标的查询字串将存放在Request的属性Query中。如果查询字串是由"键值对"所构成的,且各键值对之间用&联结起来,例如
----name=dog&color=black
----则还会将各个键值对拆开,再将每一对中的"键"和"值"存放在Request的属性QueryFields中。QueryFields是Tstrings类型的对象,其属性Names和Values分别存放各个键值对的"键"和"值"。应用程序通过访问这些属性,便可知当前的查询是什么。
----如果接收到的请求消息是用POST方法传送表单的操作结果,则如上所述,操作结果将是用&联结多个名值对的一串字串,这一字串将存放在Request的属性Content中,并且i将分析这些键值对,将每一对中的"键"和"值"存放在Request的属性ContentFields中。ContentFields和QueryFields一样,都是TStrings对象,通过其属性Names和Values可获得各个键值对的"键"和"值"。
----以上分析使我们知道当前请求消息的详细情况。无论对请求如何处理,最终我们必须返回一些信息给浏览器。通常是应用程序将处理结果写成一个HTML文件,逐行写入Respons的属性Content中。也可以利用Delphi的控件PageProducer编写HTML文件,然后将PageProducer的内容赋值给Response的属性Content,返回给浏览器。
----Response是TwebResponse类型的对象,其属性Allow,ContentEncoding,ContentLength,ContentType,Date,Expires,...等对应于响应消息中消息头的各个字段,应用程序如果需要设置这些字段的值,则可在以上响应过程中设置Response的相应属性值。
----响应过程最后的参数Handled用来说明响应动作是否已完成。
1018

被折叠的 条评论
为什么被折叠?



