GeoServer源碼解析和擴展 (一)基礎篇

GeoServer源碼解析和擴展 (一)基礎篇

一 緣起

    一直在使用GeoServer,從來沒關心它的實現。也是GeoServer設計的實在太好,下載,安裝,啓動頁面,根本不費力。這是其一,其 二,GeoServer遵循OpenGIS的開放標準WMS,WFS,WCS,這3個標準涵蓋了大部分WebGIS基礎應用,一般情況下不太需要在服務端 做什麼開發了。

    那麼會不會有不一般的情況呢?如果直接用GeoServer實現業務級別的REST服務是不是會更高效呢?如果搞清楚它的結構遇到奇怪問題時是不是就不必 到處求人了呢?如果,也許只是如果,有一天你自己不得不實現一個服務器,今天的學習是不是會有所幫助呢?除去以上原因,難道你就不想知道它是怎麼工作的 嗎?好了,不再廢話了,讓我們趕快開始吧。

二 預備

1)下載源碼,我使用的是最新穩定版2.0.2;

2)下載工具,JDK,Eclipse,Maven,SVN,這些東東可以去官網下載;

3)跟着說明,產生Eclipse項目(這個過程比較耗時);

4)打開項目,會看見下面這些包(其實還有很多插件之類的包,我都刪除了)

image

5)可以從Eclipse啓動GeoServer了。

image

如果你已經安裝了GeoServer,現在也可以打開它的登陸頁面進行操作。

三 結構

    在深入代碼之前,先來熟悉一下代碼的結構。所有“web”打頭的包暫時可以不關心,注意力集中在“platform”,“main”,“ows”,“wfs”,“wcs”,“wms”這6個包上。我簡單介紹下它們的關係,下圖

image

展現了包之間的依賴關係,下面的包依賴上面的包,最頂端是“platform”。

    “platform”,“ows”和“main”(這3個完全可以合在一起嘛)包含了GeoServer最基礎最核心的類和接口,下面介紹一些重要的類和接口,wfs”,“wcs”,“wms”將利用這些類來完成具體的功能

1)platform包的org.geoserver.platform.Service類代表一個具體的服務,例如WMS,它用ID和VERSION來唯一標定,每一個服務都會提供若干操作(Operation);

2)platform包的org.geoserver.platform.Operation類代表某個服務下可以被請求的操作,例如GetCapabilities,這個類利用Java的反射機制;

3)ows包的org.geoserver.ows.Dispatcher類處理所有OWS的請求,這個類將是我們調試的重點,我們會在後面的章節詳細描述它;

4)main包的org.geoserver.catalog.Catalog接 口包含資源訪問的方法,這些資源有“Layer”,“Layer Group”,“Map”,“Namesapce”,“Resource”,“Store”,“Style”和“Workspace”,我們會在後面對這 些資源做詳細的講解,瞭解了它們就知道GeoServer是如何組織和使用數據的了;

5)main包的org.geoserver.config.GeoServer接口包含訪問服務器公共配置信息的方法,我們將會在很多場合看到它;

6)main包裏面還有一些描述資源的接口,例如org.geoserver.catalog.LayerInfo代表“Layer”資源,這些接口我們也會在後面的章節逐一介紹。

四 第三方庫

    GeoServer使用了近百個第三方軟件包(豐富第三方軟件包也許是Java最迷人也最迷惑人的地方)。下面我會介紹一些我認爲比較重要或者比較有趣的:

1)GeoTools可以說是Java語言的GIS標準包,它繼承了GeoAPI,一個符合OGC簡單要素訪問協議(Simple Feature Access)的Java包,提供了大量GIS操作,包括多種格式的空間數據源訪問,地圖渲染,空間幾何操作,GeoServer的GIS部分完全使用它來實現;

2)SpringFramework是一個程序框架(wiki的解釋),GeoServer用它來構建運行時環境,我們會在“main”,“wcs”,“wfs”和“wms”下面看到這樣一個文件“applicationContext.xml”,這個文件告訴spring框架需要創建哪些類實例,以及如何創建。下面來看個典型配置:

image

這是“main”的配置文件的一部分,它構建一個基本的運行環境;

3)FreeMarker 是一個模板引擎(官網的定義),用它提供的模板語言,我們可以很容易實現對象模型與輸出格式的分離,GeoServer用它來實現某些HTML文本的輸出 (我覺得GeoServer對FreeMarker的使用還不夠充分,我會把所有的文本輸出全部交給它來完成)。

五 預演

    本文的最後讓我們來看看我們將如何深入GeoServer的代碼。方法很簡單,就是下斷點然後跟蹤調試。我們知道WMS裏面最基本的方法是GetCapabilities,因此我們在wms包裏尋找與“GetCapabilities”相關的內容,很快就發現了類org.vfny.geoserver.wms.responses.WMSCapabilitiesResponse,姑且先不管它是什麼反正和GetCapabilities有關,在繼續查看了它的代碼後,確認“execute”函數是關鍵。我們啓動程序,然後在execute裏面下斷點,如下圖:

image

現在我們在瀏覽器裏敲入這個地址“http://localhost:8080/geoserver/wms?request=getCapabilities”,回車。程序停留在斷點處,這時我們重點來看調用棧,如下圖:

image

我們發現,原來調用是Dispatcher的response方法傳遞來的。打開Dsipatcher類的代碼仔細查看,很快(其實花了我半天的時間)理清了它處理請求的過程,用僞代碼描述如下:

//解析HTTP請求,創建請求參數

var request = parseRequestParams(requestURL);

//通過SERVICE和VERSION來尋找合適的服務對象

var service = findService(request.SERVICE,request.VERSION);

//創建執行對象

var operation = buildOperation(service,request.REQUEST,request.PARAMS);

//執行操作,返回結果

var result = execute(operation);

//將結果寫入返回流

response(result,request,operation);

到此我們可以確定Dispatcher類是處理請求的核心,一切就從這裏開始。下一章我們將用同樣的流程來分析GeoServer,最終我們會完全弄清楚它的工作原理,並且學會如何對它進行擴展。

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