GeoServer源碼解析和擴展 (二)註冊服務

   先上源碼下載

    上一章我們介紹了GeoServer源碼分析的必要性(這個就見仁見智了)以及諸項準備工作,並且在最後還給出了OWS請求處理流程的僞代碼。

    這一章我們來看看要註冊自己的服務需要做哪些工作。假設我們要爲一個物流公司GOODS開發系統,有一個功能是給定起點和終點的城市名稱以及包裹的重量返回運費,運費的計算公式如下:

                     運費(¥) = 距離(千米) X 貨物重量(千克)

我 們需要知道城市間的距離,這就需要用到GIS系統(當然也可以不用),假設已經部署了GeoServer服務器(個人以爲如果要求不高或者錢沒有多到燙 人,使用這種免費的軟件足夠用了)。基本設計是這樣的,爲GeoServer註冊一個新的服務“trans”,它有一個方法“GetOutlay”,方法 參數是:起點“FROM”,終點“TO”,貨物質量“WEIGHT”,返回運費。下面是一個典型的請求:

http://localhost:8080/geoserver/trans?request=GetOutlay&from=Chengdu&to=Shanghai&weight=100

    讓我們來看看要註冊一個服務都需要做些什麼。以wms爲例,在wms包的applicationContext.xml文件裏有如下片段。

image

首先,我們需要創建一個Java項目“trans”,然後在項目中包含配置文件“applicationContext.xml”

image

在配置文件裏添加如下片段

image

爲項目增加一個類com.goods.TransService,它有一個公共方法GetOutlay,這個方法可以沒有參數也沒有返回值。爲了能在Eclipse裏面運行,我們需要把“trans”項目增加到“web-app”項目的依賴關係裏

image

我們有了一個服務類並且註冊到了運行時環境裏,現在我們需要讓Servlet找到它,打開web-app下面的的web.xml文件

image

在裏面添加下面一段

image

然後在本項目的配置文件中增加下面一段

image

現在,啓動GeoServer,在瀏覽器中敲入“http://localhost:8080/geoserver/trans?request=GetOutlay&from=Chengdu&to=Shanghai&weight=100”,回車。瀏覽器頁面爲空,沒有報錯,表示服務註冊成功了,但是這個服務還沒有任何功能。

    繼續以WMS爲例,來看看DefaultWebMapService類的GetMap函數

image

它 有一個參數GetMapRequest和一個返回值GetMapResponse,GetMapRequest是從 org.vfny.geoserver.Request繼承來的,而GetMapResponse實現了 org.vfny.geoserver.Response接口,這兩個抽象類在Dispatcher處理請求時會用到。先不多想,照貓畫虎,於是我們有了 GetOutlayResponse和GetOutlayRequest

image

然後修改TransService的代碼如下

image

再次啓動項目,運行例子,我們得到這樣一條異常

image

異常是從Dispatcher的dispatch函數拋出的,因爲沒有找到創建GetOutlayRequest的reader。於是我們再次到wms的配置文件裏取經,請看下面這段

image

看來我們還需要一個叫GetOutlayKvpReader的類。增加GetOutlayKvpReader到“trans”項目

image

並且在配置文件中添加如下信息

image

仔細研究GetMapKvpRequestReader的代碼之後,寫出GetOutlayKvpReader的代碼,如下:

image

Dispatcher將會利用這個類從請求參數裏創建GetOutlayRequest對象。再次運行程序,又出現一個異常

image

這一次是Dispatcher的response函數拋出,大意是找不到處理GetOutlayResponse類型的response。再一次,從wms的配置文件中我們找到了這樣一段

image

這說明我們還需要把GetOutlayResponse註冊到運行時中去,在本項目的配置文件中添加如下信息

image

這一次運行程序,瀏覽器沒有拋出異常,但還是沒有結果。

    來回想一下我們的設計:找到兩個城市,計算距離,計算運費,輸出。城市名稱是從請求參數裏獲得的,並且已經由GetOutlayKvpReader將它們 保存到GetOutlayRequest對象裏面,現在需要查詢城市地理座標。通過研究GetMapResponse的代碼,我們決定把這部分代碼放到 GetOutlayResponse的execute函數中,並且需要用到Catalog對象,這個對象可以查詢已經部署的要素類型(測試數據在此下載,如何部署可以參看這篇文章)。我們需要把Catalog對象傳給GetOutlayResponse,而GetOutlayResponse又是在TransService裏面創建的,所以我們應該把Catalog傳給TransService。先來修改TransService的代碼

image

然後修改配置文件裏面註冊服務的那一段,添加引用Catalog的信息

image

如果你對變量“catalog”感到迷惑的話,可以去看看main包的配置文件,這個變量是這裏創建的

image

不難看出,Catalog在整個GeoServer中只有一個實例。最後完成GetOutlayResponse的execute函數

image

和writeTo函數

image

啓動程序,運行請求,會得到如下結果。

image

這表示我們的服務能夠工作了。

    將這個項目輸出成jar文件,然後將jar文件複製到目錄“[GeoServer安裝目錄]\webapps\geoserver\WEB-INF \lib”下,按照前面步驟修改“[GeoServer安裝目錄]\webapps\geoserver\WEB-INF\web.xml”文件,啓動 GeoServer,運行請求,會得到同樣的結果,大功告成。

    本章我們快速的實現了一個服務,並且將它註冊到GeoServer中。但是留下了很多疑問,這些疑問不搞清楚,就只能算知其然而不知所以然。下一章我會重點介紹GeoServer的結構,到時候本章許多疑問將會迎刃而解。

發佈了16 篇原創文章 · 獲贊 10 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章