用 C++ 實現類似於 JAVA HttpServlet 的程式設計介面

鄭樹新發表於2016-08-24

網際網路剛興起時,很多專案都是用 C /Perl 語言寫的一大堆 CGI,一些老程式設計師可謂是償盡了程式設計的苦,因為那時國內的技術水平普遍比較低,如果你會 CGI 程式設計,就已經算是行業中人了,如果你對 CGI 程式設計比較熟練,則就可以稱得是“專家”了,後來技術不斷進步,各種國外的新技術都進入中國並不斷得到普及,CGI 就逐漸淪為一種落後的技術,後來的 PHP, JSP/Servlet, ASP 逐漸佔領了 WEB 程式設計的技術市場,這個時候如果你說再用 C 寫 CGI,別人會感覺是在和古人對話。

現在主流的 WEB 開發語言一個很大的優勢就是有各種相對成熟的基礎庫和框架,開發效率很高,而 CGI 則就遜色很多。當然,這些語言也得有執行效率相對較低的問題,畢竟它們都是指令碼語言或半編譯語言,需要虛擬機器解釋執行,象 facebook 的 WEB 前端基本都是用 PHP 寫的,他們為了解決執行效率問題,在一位華人的領導下開發了可以將 PHP 程式碼轉成 C++ 程式碼的工具(hiphop),從而使執行效率大大提高,這也從另一個側面反映出技術人員還是希望他們的程式能夠執行的更快些。

本文主要描述了 acl_cpp 庫中有關 WEB 程式設計的方法類,為了使大家容易上手,其中的介面設計及命名儘量模仿 JAVA HttpServlet 等相關的類(希望 Oracle 不會告我侵權,呵呵)。如果您會用C/C++程式設計,同時又有使用 Java Servlet 進行 WEB 程式設計的經驗,則該文您讀起來一點不會費力,當然如果您多年從事 WEB 開發,我想理解這些類的設計及用法也不應該有什麼難度。好了,下面就開始講如何使用 acl_cpp 庫中的 http/ 模組下的類進行 web 程式設計。

在 acl_cpp/src/http 模組下,有幾個類與 WEB 程式設計相關:HttpServlet,HttpServletRequest, HttpServletResponse, HttpSession, http_header, http_mime, http_client。如果您掌握了這幾個類的用法,則進行 WEB 程式設計就不會有什麼問題了,下面一一介紹這幾個類:

一、HttpServlet 類

建構函式及解構函式:

在構建函式中,為了支援 HttpSession 資料的儲存,需要使用者給出 memcached 的伺服器地址(目前僅支援採用 memcached 來儲存 session 資料,將來應該會擴充套件至可以支援 redis 等),同時使用者還需要給出 session 的 cookie ID 識別符號以發給瀏覽器。

四個虛介面,需要子類實現以應對不同的瀏覽器的 HTTP 請求:

使用者實現的 HttpServlet 子類中可以實現以上幾個虛介面的一個或者幾個,以滿足不同的 HTTP 請求。

下面的函式為 HttpServlet 類開始執行的函式:

從上面五個虛方法中,可以看到兩個重要的類:HttpServletRequest 和 HttpServletResponse。這兩個類分別表示 http 請求類及 http 響應類,這兩個類都是由 HttpServlet 類物件建立並釋放的,所以使用者不必建立和銷燬這兩個類物件例項。下面分別介紹這兩個類:

二、HttpServletRequest  類

該類主要是與瀏覽器的請求過程相關,您可以通過該類的方法獲得瀏覽器的請求資料。該類的方法比較多(基本上是參照了 java HttpServlet 的功能方法及名稱),所以下面僅介紹幾個主要的方法:

以上方法一般都是我們在實際對 HttpServletRequest 類方法使用過程中用得較多的。如:

getParmeter: 用來獲得 http 請求引數

getCookieValue:獲得瀏覽器的 cookie 值

getSession:獲得該 HttpServlet 類物件的 session 會話

getInputStream:獲得 http 連線的輸入流

getContentLength:針對 HTTP POST 請求,此函式獲得 HTTP 請求資料體的長度

getRequestType:針對 HTTP POST 請求,此函式返回 HTTP 請求資料體的傳輸方式(普通的 name=value 方式,multipart 上傳檔案格式以及資料流格式)

 三、HttpServletResponse 類

該類主要與將您寫的程式將處理資料結果返回給瀏覽器的過程相關,下面也僅介紹該類的一些常用的函式,如果您需要更多的功能,請引數 HttpServletResponse.hpp 標頭檔案。

setCharacterEncoding:該方法設定 HTTP 響應頭的 HTTP 資料體的字符集,如果通過該函式設定了字符集,即使您在返回的 html 資料中重新設定了其它的字符集,瀏覽器也會優先使用 HTTP 響應頭中設定的字符集,所以使用者一定得注意這點;

setContentType:該方法用來設定 HTTP 響應頭中的 Content-Type 欄位,對於 xml 資料則設定 text/xml,對 html 資料則設定 text/html,當然您也可以設定 image/jpeg 等資料型別;當然,您也可以直接通過該方法在設定資料型別的同時指定資料的字符集,如可以直接寫:setContentType(“text/html; charset=utf8”),這個用法等同於:setContentType(“text/html”); setCharacterEncoding(“utf8”)

setStatus:設定 HTTP 響應頭的狀態碼(一般不用設定狀態碼,除非是您確實需要單獨設定);

addCookie:在 HTTP 響應頭中新增 cookie 內容;

sendHeader:傳送 HTTP 響應頭;

getOutputStream:該函式返回輸出流物件,您可以向輸出流中直接寫 HTTP 響應的資料體(關於 ostream 類的使用請引數標頭檔案:include/ostream.hpp)。

除了以上三個類外,還有一個類比較重要:HttpSession 類,該類主要實現與 session 會話相關的功能:

四、HttpSession 類

該類物件例項使用者也不必建立與釋放,在 HttpServet 類物件內容自動管理該類物件例項。主要用的方法有:

只所以將這兩個方法宣告為虛方法,是因為 HttpSession 的 session 資料儲存目前僅支援 memcached,您如果有精力的話可以實現一個子類用來支援其它的資料儲存方式。當然您也可以在您實現的子類中實現自己的產生唯一 session id 的方法,即實現如下虛方法:

好了,上面說了一大堆類及類函式,下面還是以一個具體的示例來說明這些類的用法:

五、示例

下面的例子是一個 CGI 例子,編譯後可執行程式可以直接放在 apache 的 cgi-bin/ 目錄,使用者可以用瀏覽器訪問。

 參考:

acl網路通訊與伺服器框架下載地址:https://github.com/zhengshuxin/acl

相關文章