Web應用程序是運行在服務器端的可執行程序或動態鏈接庫。它們可以響應用戶要求,動態產生超文本頁面,並將信息提供給客戶浏覽器。
由於Web應用程序的標准並不相同,程序的寫法各異,這樣就給開發者造成不小的困擾,因為開發人員不太可能了解每一種標准的寫法。而C++ Builder可以很好地解決這個問題。 C++ Builder將Web應用程序的開發封裝成組件,使開發者面對一致的開發界面,使用一致的開發原理,惟一不同的地方在於開始產生程序時所選擇的程序結構,至於程序的編寫細節和方式都一模一樣。本文通過兩個實例介紹利用C++ Builder開發Web應用程序的具體步驟。
簡單的Web程序
首先,點擊C++ Builder IDE 的菜單項File|New option,選中 Web Server Application 圖標.
由於CGI(Common Gateway Interface)運行時需要一個獨立的進程,而ISAPI/NSAPI動態鏈接庫運行時要映射到Web服務器進程中,所以ISAPI/NSAPI需要的資源比CGI要少。但ISAPI/NSAPI動態鏈接庫的這個特點為調試程序造成了一定的困難,因此較好的辦法是先創建一個CGI程序,並進行調試,然後再把它轉化成ISAPI/NSAPI動態鏈接庫。所以在這裡選擇"CGI Standalone executable",生成一個TWebModule 對象。
Web應用程序實際上是Web服務器在功能上的擴展,就好像Windows應用程序是Windows在功能上的擴展一樣。當Web應用程序從Web服務器檢索到一個HTTP請求消息時,就對HTTP請求消息進行分析,生成HTML頁面傳遞給Web服務器,再由Web服務器傳遞給客戶。C++ Builder Web應用程序的一個關鍵部件是Web Module,它收集和管理著一組TwebActionItem對象,用TwebRequest對象來描述HTTP請求消息,並根據HTTP請求消息來指派其中一個動作去響應客戶的請求,實際上就是填寫TWebResponse對象的Content特性。
一個Web應用程序可以創建若干個動作項,以供Web調度器(TwebDispatcher)指派。C++ Builder 是用一個專門的動作項編輯器(Action Editor)來創建和管理動作項的。右鍵單擊Web模塊,在彈出的菜單中選擇"Action Editor"命令。然後添加一個動作項,通過它的PathInfo屬性可以設置動作項在Web服務器上的入口路徑,而default屬性設置當PathInfo屬性為空時該動作項是否執行。
為該動作項編寫如下代碼:
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參數來訪問客戶的請求消息。要響應客戶的請求,實際上就是把用HTML描述的頁面賦值給Response的Content屬性,Web調度器會自動把相應結果傳遞給Web服務器,再由Web服務器傳遞給客戶。
至此,一個簡單的Web應用程序創建完畢,現在可以通過Web浏覽器測試它(運行界面如圖3所示)。要注意的是Web應用程序所在路徑應有可執行權限。
處理用戶輸入的Web程序
下面在上述例子的基礎上繼續創建一個用於處理用戶輸入的Web程序。再添加一個動作項TWebActionItem。在WebModule1加入TPageProducer 對象,利用它事先准備好的HTML模板生成HTML文檔。
首先,利用Microsoft FrontPage 做一個運行後如圖5所示的用戶輸入表(HTML代碼略)。
為TWebActionItem2的OnAction 事件編寫如下代碼:
void __fastcall TWebModule1::WebModule1WebActionItem2Action(TObject *Sender, TWebRequest *Request, TWebResponse *Response,bool &Handled)
{
Response->Content=PageProducer1->Content();
}
然後處理用戶輸入,把用戶輸入寫入一個新的HTML頁面。這就需要再增加一個TpageProducer組件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];
}
繼續增加一個動作項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按鈕。