<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    內蒙古java團隊

    j2se,j2ee開發組
    posts - 139, comments - 212, trackbacks - 0, articles - 65
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    MapGuide源碼分析【

    Posted on 2011-04-15 00:24 帥子 閱讀(376) 評論(0)  編輯  收藏 所屬分類: MapGuide

    本節中,我們將通過介紹如何完成枚舉資源功能來介紹MapGuide Web擴展的部分源代碼。

    在瀏覽器端的地址欄輸入類似如下字符串,就會發送一個枚舉資源的HTTP請求。

    http://hostname/mapGuide/mapagent.fcig?OPERATION=EnumerateResources&VERSION=1.0.0& RESOURCEID=Library:// &TYPE=FeatureSource&DEPTH=3

    下面我們來看看MapGuide Web擴展如何處理這個請求。

    在介紹MapGuide Web擴展如何處理枚舉資源HTTP請求之前,讓我們首先來看看MapGuide Web擴展用于處理HTTP請求和響應的類,這些類的類圖如圖19?4所示。

    clip_image002

    圖 19?5 HTTP請求和響應類的類圖

    類MgHttpRequest和類MgHttpResponse分別是對HTTP請求和響應結果的抽象,這兩個類可以用于任何類型的Web應用服務器,也就是說它們的代碼不依賴于任何Web應用服務器API。在文件夾“\MgDev\Web\src\HttpHandler”下可以找到所有前綴為“MgHttp”類的源代碼。

    類MgHttpRequest用于處理HTTP請求,它包含了一個HTTP請求頭MgHttpHeader的實例、一個HTTP請求參數HttpRequestParam的實例和一個HTTP請求元數據HttpRequestMetadata的實例。調用方法MgHttpRequest::Execute()會將HTTP請求轉發給MapGuide服務器,當MapGuide服務器處理完這個請求,將請求結果返回給Web擴展之后,這個方法會返回一個MgHttpResponse對象,它表示HTTP請求的響應結果。

    接下來讓我們看看MapGuide Web擴展如何處理枚舉資源的HTTP請求。大多數MapGuide用戶都是使用IIS作為Web應用服務器,并且使用Web擴展模塊isapi_MapAgent.dll來處理HTTP請求,所以本節側重于isapi_MapAgent.dll模塊處理HTTP請求的流程,這個處理流程的時序圖如圖19?5所示。

    clip_image004

    ?19?6 Web擴展處理枚舉資源請求的時序圖

    1) 加載Web應用服務器擴展模塊

    如果使用的是IIS Web應用服務,那么在接收到后綴為“fcgi”的HTTP請求后,IIS會加載Web應用服務器擴展模塊isapi_MapAgent.dll或MapAgent.exe。其中,isapi_MapAgent.dll基于IIS API,具有更好的性能;MapAgent.exe基于CGI技術,性能要稍微差一些。如果使用的是Apache Web應用服務器,那么在Windows平臺上Apache會加載Web應用服務器擴展模塊MapAgent.exe,在Linux平臺上會加載模塊mod_mgmapagent.so。

    這三個Web服務器擴展模塊實現了類似的功能,它們的源代碼位置如表19?2所示。

    服務器擴展模塊

    源代碼位置

    isapi_MapAgent.dll

    \Web\src\IsapiAgent

    MapAgent.exe

    \Web\src\CgiAgent

    mod_mgmapagent.so

    \Web\src\ApacheAgent

    ?19?2 Web服務器擴展模塊的源代碼位置

    從圖19?6中可以看到這三個Web服務器擴展模塊提供了類似的類,這些類提供了相同的接口,類XXXPostParser用于解析HTTP請求中傳入的參數及參數值,類XXXResponseHandler用于將HTTP請求的響應結果發送給客戶端。其中,“XXX”表示“Cgi”、“Isapi”或“Apache”。

    clip_image006

    ?19?7 Web擴展的請求處理模塊

    對于模塊isapi_MapAgent.dll,每個“fcgi”類型的HTTP請求會調用此模塊中的方法HttpExtensionProc,這個方法的代碼如下所示,為了便于理解我們只保留了一些核心代碼。

    DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)

    {

    Initialize(pECB);

    // 調用GetServerVariable讀取諸如服務器名稱、端口號等服務器變量信息

    ......

    // 創建MgHttpRequest的實例,用于處理HTTP請求

    Ptr request = new MgHttpRequest(wUrl);

    // 解析HTTP請求中的參數,并且將這些參數置入MgHttpRequest對象中

    Ptr params = request->GetRequestParam();

    ......

    IsapiPostParser postParser(pECB);

    postParser.Parse(params);

    ......

    // 創建IsapiResponseHandler的實例,用于將響應請求返回給客戶端

    IsapiResponseHandler responseHandler(pECB);

    ......

    // 將HTTP請求轉發給MapGuide服務器,當MapGuide服務器處理完這個請求,

    // 將請求結果返回給Web擴展之后,這個方法會返回一個MgHttpResponse對象,

    // 它表示HTTP請求的響應結果。

    Ptr response = request->Execute();

    // 將響應結果返回給客戶端

    responseHandler.SendResponse(response);

    ......

    }

    2) 創建MgHttpRequest的實例,用于處理HTTP請求

    在加載Web應用服務器擴展模塊后,需要創建一個MgHttpRequest的實例用于處理HTTP請求。類MgHttpRequest并不關聯與任何類型的Web應用服務器,所以Web應用服務器擴展模塊會使用類XXXPostParser解析HTTP請求中傳入的參數及參數值,將這些參數設置到MgHttpRequest對象中。

    3) 調用方法MgHttpRequest::Execute()處理HTTP請求

    方法MgHttpRequest::Execute()的源代碼如下所示。為了便于理解,我們同樣只保留了一些核心代碼。

    MgHttpResponse* MgHttpRequest::Execute()

    {

    Ptr hResponse;

    Ptr result;

    // 創建MgHttpResponse對象,用于返回HTTP請求響應結果

    hResponse = new MgHttpResponse();

    result = hResponse->GetResult();

    // 獲得HTTP請求中參數“OPERATION”的值

    STRING sParamValue = m_requestParam->GetParameterValue(MgHttpResourceStrings::reqOperation);

    ......

    // 根據參數“OPERATION”的值取得對應操作的請求響應處理器

    Ptr rrHandler =

    CreateRequestResponseHandler(sParamValue, result);

    .......

    // 處理HTTP請求

    if(rrHandler != NULL) rrHandler->Execute(*hResponse);

    ......

    // 返回響應結果

    return SAFE_ADDREF((MgHttpResponse*)hResponse);

    }

    每個HTTP請求中包含一個參數“OPERATION”,它用于代表操作的類型。對于不同的操作,MapGuide定義了不同的請求響應處理器類,這個類會調用MapGuide服務中對應的方法處理這個操作,這些請求響應處理器類的類圖如圖19?7所示。從圖19?7可以看到,所有請求響應處理器類都繼承自類MgHttpRequestResponseHandler,每一種操作都有一個對應的子類,例如枚舉資源操作使用了類MgHttpEnumerateResources,描述模式操作使用了類MgHttpDescribeSchema。

    clip_image008

    ?19?8 HTTP請求響應處理器的類圖

    MapGuide定義了一個全局map對象用于存放每種操作對應的請求響應處理器類對象,它的鍵是操作的名稱,值是請求響應處理器類對象。

    // 定義一個全局map對象,用于存放每種操作對應的請求響應處理器類對象

    static map

    httpClassCreators;

    bool InitializeStaticData()

    {

    httpClassCreators[MgHttpResourceStrings::opGetMap] =

    MgHttpGetMap::CreateObject;

    httpClassCreators[MgHttpResourceStrings::opGetMapUpdate] =

    MgHttpGetMapUpdate::CreateObject;

    httpClassCreators[MgHttpResourceStrings::opGetDrawing] =

    MgHttpGetDrawing::CreateObject;

    ......

    httpClassCreators[MgHttpResourceStrings::opDescribeDrawing] = MgHttpDescribeDrawing::CreateObject;

    httpClassCreators[MgHttpResourceStrings::opEnumerateResources] = MgHttpEnumerateResources::CreateObject;

    ......

    }

    調用方法MgHttpRequest::CreateRequestResponseHandler(...)可以根據操作的名稱獲得對應的請求響應處理器類對象。對于枚舉資源操作,它會返回一個類MgHttpEnumerateResources的對象。

    調用這些請求響應處理器類的Execute(…)方法,會創建一個代理服務類對象,然后調用代理服務中對應的方法。為什么說創建的是一個代理服務類對象呢?我想看完圖19?8之后大家會有所明白。從圖19?8中可以看到,所有的MapGuide服務有兩個子類,一個是名稱為MgProxyXXXService的代理服務類,它是MapGuide Web擴展端的一個類,另一個是名稱為MgServerXXXService的服務器服務類,它是MapGuide服務器端的一個類。MgProxyXXXService最終會將服務請求轉發給服務器端類MgServerXXXService,所以說真正處理服務請求的類是MgServerXXXService,MgProxyXXXService僅僅起到一個轉發的作用,這也就是為什么稱類MgProxyXXXService為代理服務類的原因。

    clip_image010

    ?19?9 代理服務和服務器服務類的類圖

    對于枚舉資源操作,MgHttpEnumerateResources::Execute(...)的源代碼如下所示。調用這個方法會創建一個代理資源服務類MgProxyResourceService的對象,然后調用MgProxyResourceService::EnumerateResources(...)枚舉資源,最后將操作的執行結果放入MgHttpResponse對象中。

    void MgHttpEnumerateResources::Execute(MgHttpResponse& hResponse)

    {

    Ptr hResult;

    hResult = hResponse.GetResult();

    // 檢查HTTP請求中的參數

    ValidateCommonParameters();

    // 創建MgProxyResourceService實例

    Ptr mgprService =

    (MgResourceService*)(CreateService(MgServiceType::ResourceService));

    ......

    // 執行枚舉資源操作

    Ptr byteReader = mgprService->

    EnumerateResources(&mgrIdentifier, m_depth, m_type, m_computeChildren);

    // 如果需要,轉換響應請求的格式

    ProcessFormatConversion(byteReader);

    // 將操作結果放入響應請求中的MgHttpResult對象

    hResult->SetResultObject(byteReader, byteReader->GetMimeType());

    }

    MgByteReader* MgProxyResourceService::EnumerateResources(

    MgResourceIdentifier* resource, INT32 depth, CREFSTRING type,

    INT32 properties, CREFSTRING fromDate, CREFSTRING toDate,

    bool computeChildren)

    {

    MgCommand cmd;

    cmd.ExecuteCommand(m_connProp,

    MgCommand::knObject,

    MgResourceService::opIdEnumerateResources,

    7,

    Resource_Service,

    BUILD_VERSION(1,0,0),

    MgCommand::knObject, resource,

    MgCommand::knInt32, depth,

    MgCommand::knString, &type,

    MgCommand::knInt32, properties,

    MgCommand::knString, &fromDate,

    MgCommand::knString, &toDate,

    MgCommand::knInt8, (int)computeChildren,

    MgCommand::knNone);

    SetWarning(cmd.GetWarningObject());

    return (MgByteReader*)cmd.GetReturnValue().val.m_obj;

    }

    4) 將HTTP請求的響應結果返回給客戶端

    調用MgHttpRequest::Execute()會返回一個MgHttpResponse對象,這個對象包含了HTTP請求的響應結果。不過,還需要調用方法XXXResponseHandler::SendResponse(...),這樣Web應用服務器才會將這個響應結果返回給客戶端。

    主站蜘蛛池模板: 99无码人妻一区二区三区免费| 女人18毛片a级毛片免费视频| 91亚洲性爱在线视频| 成人毛片免费视频| 国产va免费精品| 亚洲沟沟美女亚洲沟沟| 国产91在线免费| 久久久精品2019免费观看| 亚洲AV无码专区国产乱码不卡| 亚洲国产成人片在线观看| 免费无码AV电影在线观看| 大妹子影视剧在线观看全集免费| 亚洲女人18毛片水真多| 亚洲精品成人片在线观看| 无码国产精品一区二区免费式影视| 无码日韩人妻AV一区免费l| 91久久亚洲国产成人精品性色 | 三年片在线观看免费观看高清电影| 免费精品国产自产拍在线观看| 亚洲综合无码一区二区三区| 亚洲成人影院在线观看| 一级女人18毛片免费| 你懂的免费在线观看| 亚洲国产精品无码久久久秋霞1 | 精品丝袜国产自在线拍亚洲| 亚洲熟妇无码八AV在线播放| 暖暖在线日本免费中文| 毛片免费全部播放无码| 久久www免费人成精品香蕉| 亚洲欧美日韩综合久久久久| 亚洲精品无码不卡| 在线观看亚洲天天一三视| 成人免费无码大片A毛片抽搐色欲| 拍拍拍无挡视频免费观看1000| 久久亚洲精品无码网站| 亚洲av永久综合在线观看尤物| 亚洲AV天天做在线观看| 红杏亚洲影院一区二区三区| 国产乱人免费视频| 日本不卡在线观看免费v| 国产卡一卡二卡三免费入口 |