加入RUN!PC粉絲團
最近新增的精選文章
 
最多人點閱的精選文章
 
 
精選文章 - 開發技術
分享到Plurk
分享到FaceBook
 
網頁應用開發的聖杯—Grails
文‧圖/許智堯 2013/10/11 下午 05:29:02



動態頁面網站(或稱網頁應用;web applications)一直都是資訊系統開發中非常重要的部份。Java陣營自1999年發佈J2EE標準以及JSP/Servlet技術以來,在網頁應用的開發上就不曾缺席過。隨著時間演進,Java網頁應用開發的各式方法論與框架也相繼被提出,除了早期的Struts MVC框架、SUN提出的JSF之外,專注於網頁應用開發各部份的框架也一一出現,例如運用於資料持久性的Hibernate、提供相依性注射(Dependency Injection;簡稱DI)的Spring等,這些工具似乎已成為了Java網頁應用開發時的標準工具組合。這類框架風靡的程度,幾乎是只要一談到要以Java建立網頁應用,大家想到的就是要趕快匯入Struts + Hibernate + Spring這幾個函式庫。

但是,這些工具雖提供了優異的效能與良好的可擴充性,卻也形成了開發者在進入Java網頁應用開發時的巨大門檻。因此,一些專注於敏捷開發的開發者開始反思:「那麼複雜的框架組合對於建立網頁應用真的是有必要的嗎?」於是,近年來也開始出現了標榜簡單、易用、開發迅速,卻又同時能夠擁有JVM架構好處的網頁應用開發框架,例如使用Scala語言的Play、使用Groovy語言的Grails等。這些新一代的Java網頁開發框架與舊世代的工具產生了衝突,他們也各擁有愛好者支持;在今年7月,知名資訊技術網站ZeroTurnaround發表了一篇文章來比較各個Java框架:The Curious Coder’s Java Web Frameworks Comparison: Spring MVC, Grails, Vaadin, GWT, Wicket, Play, Struts and JSF。令人意外的,這份評比中勝出的並不是有名的Struts或GWT,而是使用人數較少的Grails。Grails目前是由Spring Source所維護的一個開放原始碼專案,它標榜的是能透過Groovy語言的敏捷特性來進行Java網頁應用的開發,同時充分利用Hibernate與Spring等框架的好處。我們今天希望能利用這短短的篇幅,與大家介紹這個可能是Java網頁開發框架的聖杯 -- Grails。

Groovy --- 敏捷的Java
Grails框架所使用的語言為Groovy,其官方網站對他的敘述為「an agile and dynamic language for the Java Virtual Machine」,意指一種敏捷與動態的JVM語言。Groovy的開發靈感起源自Python、Perl等腳本式語言(scripting language)的優點;其程式碼相對於同等功能的Java程式碼表達性更強、更加簡潔。
Groovy與Java同樣都是JVM(Java Virtual Machine)語言,JVM語言指的是該語言在經過編譯後,其實際用於執行的二進位內容為JVM所能使用的bytecode格式,這類型的語言會有與Java相同的優點:諸如能夠跨平台、具有較高的安全性以及擴展性更佳等。
此外,Groovy的另一特色即為對DSL(Domain-Specific Language)的建構能力。DSL的建構能力可以讓程式語言在某些特定的使用情境中設定更自然簡潔的語法,提高使用者在該情境中的開發效率。而Grails的核心精神之一,正是試圖簡化Java網頁應用的種種複雜設定,因此Groovy對DSL的支援恰好可以用來作為簡化這類設定的強力工具。綜合以上各點,Grails的發起者才會挑選Groovy作為該框架的開發語言,這在目前看來也是非常正確的決定。

面面俱到的Grails的架構
前面我們有提到許多以Java為基礎而開發的框架,他們都有著許多強大的功能,身為一個開發者你可能會想問,「既然有這麼多框架,那我該選哪些呢?要怎麼搭配比較好?」這種感覺猶如走進一家菜色玲郎滿目的餐廳,使得不了解菜色的客人感到措手不及。套餐模式解決了這個問題,他把菜都配的好好的,省去了挑選的麻煩,Grails就是這種套餐的概念,他是一個full-stack的框架,整合了許多熱門開放原始碼技術包括:
● Spring:一個應用程式框架,提供了輕量級的容器,並實現了Inversion of Control (IoC)的概念,IoC讓元件之間處於鬆散偶合的狀態,可以做任意的抽換,降低框架移植的負擔,Grails網頁與Spring有著密不可分的關係。
● Hibernet:他提供了ORM的解決方案,其底層對資料庫的操作依賴於JDBC,使用者可以透過建立Hibernet的物件映射關係,將資料庫裏面資料表的結構與Java的物件作對應,之後對資料的存取可以由對目標物件的操作來達成。
● SiteMesh:他是一個網頁佈局與修飾的框架,可以將網頁的內容與頁面結構分離,達到共享的目的,他可以幫助開發者再由大量網頁頁面所構成的項目中建立醫治的葉面布局以及外觀,雖然他是Java所寫成的,但是也可以很容易的與其他網頁應用程式做結合。
● Tomcat:當前最火熱的Servlet容器,提供了對JSP與Servlet的支援,另外他也提供了Http伺服器,可以當作單一伺服器來運行,因為他是用Java開發的伺服器,所以可以運行在任何裝有JVM的作業系統下。
● H2:他是一個以Java為開發環境的關聯式資料庫管理系統並且可以被嵌入Java的應用程式或是以client-server模式運行,他也提供了SQL與JDBC的API供開發者使用。

我們可以把Grails與他主要的元件簡單整理成以下的架構圖:


在你使用Graiils並開發他的應用程式的時候,可能並不知道你正在使用至少三十種框架與函式庫的功能吧?實際上你也並不用知道自己正在建立Spring的框架或是Hibetnet的Mapping甚至是其他框架,你只要儘管的使用這些功能即可,這多虧了Grails在背後將這些功能整併在一起,當然在這過程中,Groovy扮演了很重要的角色。
正當你享受這些Grails所整合的強大功能的同時,你可能會想做一些替換,例如你不喜歡H2的資料庫想把它換成MySql,做得到嗎?答案是肯定的,因為Grails也是一個plugin-based的框架,他可以支援其他相關的技術以外掛程式的方式加入,如此開發者可以自由的新增自己想要的功能,或是用一個或數個外掛來取代現有的功能;其實隨著Grails版本的演進,許多原來於核心的框架已經被移出,改成以外掛程式的方式給使用者選擇與替換,比較重要的外掛有quartz(負責提供工作排程的套件)、web flow(負責處理網頁的request的套件)、Tomcat以及Hibernet,後兩者雖然已經成為外掛程式,但是仍然存在系統中作為預設框架,假如你不喜歡他們的功能,你也可以把他們換掉。

約定優先於配置原則(Convention over Configuration)
隨著網頁框架的演進,他們所提供的功能也越來越多,為了能夠讓這些功能能夠正常運作,開發者往往需要撰寫許多額外的設定檔來達到這個目的,造成了程式開發上的額外的負擔,現在在Grails上開發應用程式,你可以不用再擔心這個問題了!約定優先於配置(簡稱為CoC原則)是Grails開發的核心概念,其作法是用一些簡單的規定來取代複雜的設定,在這個規範之下系統可以幫助開發者盡可能做掉足夠多的事,所以你可以將心力花在解決問題上並且享受開發程式的樂趣而不是處理繁瑣的設定檔,這個規則通常在類別中包含了命名規則(例如controller的物件類別都是以controller結尾)以及位址規則(例如domain的物件要放在domain這個目錄之下)並伴隨著簡單的實例與靜態變數,如果你照著這些規則實作,系統將自動幫你產生程式碼與該應用對應的行為(如果是domain的類別,系統會自動產生查詢的方法),如此簡單的步驟可以節省大量生產時間,當然你也可以藉由修改設定檔來使用自己的規則,不過對於新手來說,遵循這個規則來開發將會使得他們的程式更容易維護與了解。

Grails在他的系統中針對各種人造物(artifact)定義了各種規則,這些人造物包含了大多數的應用類別,而他們之中有很多的位置都是在grails-app這個目錄之下,包括:controller、domain、service、taglib、util的程式碼以及BootStrap.groovy與UrlMapping.groovy這兩個檔案,對於這些物件,Grails使用了ArtefactHandler這個類別來處理不同的型別的人造物並且產生封裝來包覆他們的資料與屬性,附帶一提,外掛程式也會產生新的人造物類別,舉個例來說,Quartz的外掛會新增一個叫job的資料夾專門收納job的人造物類別。下圖為一個簡單的圖示描述domain、controller與service這三個物件類別的位置關係:



GORM (Grails Object Relational Mapping)
資料的儲存與處理一直是大多數網頁應用程式要解決的重要課題之一,ORM (Object Relational Mapping)架構的出現簡化了開發者對於資料庫操作的複雜度,Grails裡面的GORM(Grails ORM)即是這個架構的一種變化,透過GORM,系統將資料庫的表單與Groovy的類別物件做對應,開發者可以經由對這些物件的操作達到存取資料庫的目的,除了少數情況需要用到複雜指令來查詢資料庫的情況外,你可以不用擔心每次需要存取資料庫都還要下複雜的sql語法。
GORM在一開始設計的時候對於Hibernet有很高的依賴性,但是在隨後就因為他的實作上獨立性的需求而被重新設計(提供了NoSQL的資料存取),而現在開發者可以自由的選擇他想要把資料儲存在哪個地方。此外GORM現在也完全或部分支援MongoDB、Redis、Neo4j、Amazon SimpleDB、Riak、Gemfire與JPA等資料庫,之後也預計要支援REST、Cassandra等系統,而這些支援的套件並不會由官方來開發而是會交給社群開發來完成。

Grails的MVC模式
有使用過Ruby on Rails的人相信都對MVC的架構感到不陌生, MVC模式把系統分成模組(Model)、顯示(View)和控制器(Controller)三部分,在MVC的開發模式下,網頁的設計更加動態話,並達到簡化程式設計與擴充的效果,在Grails的系統中也同樣的使用了MVC模式,其對應的類別分別為:
●模組(Model):Grails的domain類別實做了模組功能,可以保存工作時期的資料並且實作方法來對資料進行動作,domain類別彼此間也可以建立關係包括一對一、一對多、多對一以及多對多等關係,當一個domain被建立之後,資料庫中也會建立對應的表單,以下圖例子來說明,當開發者建立了以下的domain類別:



Grails就會在運行時執行以下動作,建立user的資料表:



●顯示(View):關於Grails中的網頁呈現,你可以使用JSP來完成,不過你也可以使用GSP(Groovy Server Pages)來達到更棒的效果,GSP與JSP十分類似,他允許網頁中的動態存取,可以將server端的資訊顯示在網頁中並以Xml的方式呈現,除此之外,他也支援了Grails的標籤與Groovy的程式碼,增加開發的便利性,下面為一個簡單的GSP例子:



■ 控制器(Controller):在Grails裡controller的物件專門負責處理與回應應用程式的請求,當一個controller接收到請求之後,他會針對這個請求做某些事,最後做輸出,controller的輸出包含了以下幾種可能:
■ 叫另一個controller並運行其功能
■ 導向另一個view
■ 直接回應一串訊息,內容可以為XML也可以是JSON
Controller在Grails中扮演著重要的角色,他提供了Grails應用程式的進入點,並且決定client端會被引導到哪裡,在Grails的程式撰寫中,所有的controller類別的結尾都會加上controller,類別裡面會有它所提供的方法,如果這個方法為空,則會直接導到與方法同名的view中,controller的實例如下:



Grails的測試與環境參數
在軟體的開發過程中,測試通常對於成品的好壞有著決定重要的影響,Grails也支援了良好的測試模組與測試工具讓開發者從單元測試、整合測試到功能性測試整個流程變得更加簡單,當你在專案中建立了一個物件(可以為domain、controller或是service),Grails會同時幫你建立這個物件的單元測試類別,你可以在這個類別中加入測試方法來測試你想要測試的部分,然後再透過Grails的指令執行測試,系統會整理測試的結果顯示在網頁上,當然也可以將它輸出成檔案。
在Grails中,「環境」的設定可以帶來許多便利,基本的環境分成:development、test與production(你也可以加入你自己設定的環境),他可以讓你在定依設定檔(Boostrap.groovy、Config.groovy、DataSource.groovy)的時候,可以因為環境的設定不同而有不同的行為,在development的模式中,沒有顯著的快取需求,重新讀取的服務會隨時偵測是否有類別被修改而進行重讀,這些動作會增加系統重啟的時間;在production模式下,有明顯的快取需求而且預設不用重讀,總結來說前者是對開發環境做最佳化,後者是對效能做最佳化。第三個環境test是當你在對物件進行測試的時候會用到,在測試的環境中GORM會將測試的資料存在記憶體中而不會動到資料庫。

其他特色
除了上述所說特點外,Grails還支援了很多的功能,例如他加入了service類別的物件來幫助controller處理資料庫存取與商業邏輯的封裝;使用filter與interceptor這兩個物件在request的前後增加額外的行為;另外他也提供il8n國際化的機制;log4j可以在系統裡的人造物類別中加入log變數來處理log,完成事件的紀錄。Grails是一個開放的原始碼,你可以在GitHub上面找到他的程式碼,也可以在mailing list與roadmap上面參與他的開發討論,因此任何人都可透由回報問題或是對一個功能的回饋來幫助改善Grails的品質。

總結
經過上面的介紹我們可以知道Grail是一個很容易讓開發者上手的框架,他的系統幫助開發者處理很多事情,通常只要下一個指令或是寫少數的程式碼就可以達成你想要的目的;此外Grails的架構整合許多強大的功能,而且大多的功能都可以隨意抽換,增加了很多彈性,如果你是之前熟悉JAVA網頁框架開發的開發者,使用Grails將會幫助你更快速的結合各種Java開發的元件,節省你不少時間;Grails在網路上有完整的文件與討論社群,裡面提供了不少範例程式,幫助開發者找到問題的答案,而且現在已經有越來越多的人投入Grails的使用與開發,相信他的未來的成長是值得期待與肯定的。



本文作者許智堯現服務於資策會智慧網通系統研究所。