Wicket Beginning
http://mywicket.group.javaeye.com/group/blog_post/259300
一、概貌
Wicket是基于web應用框架的高級組件,其主要特點:
* 在HTML和java之間的明確分隔
* OO組件模式
* 自動狀態管理
* 高度生產化
* 低學習投入
* 屏蔽Servlet API、HTTP協議細節
* 無需XML配置文件
* 易于構造可重用組件
Struts是以Model2 MVC 為藍本構建的web應用框架。其工作圍繞著處理HTTP請求的action類來完成。配置方式采用XML文件。
下文將對Wicket和Struts在體系、HTTP請求處理、Servlet API和HTTP協議抽取、狀態管理、配置這六方面進行比較。
二、比較第一方面:體系
Struts體系基于解釋每個HTTP請求并將其定向到某個處理該類型請求的指定Action類。每個Action類將處理后的結果返回,并決定下一步走向——通過轉發或者重定向到另一個Action或者將控制權交給輸出HTML的JSP頁面。從技術較大來講,雖然每個部分之間做到了很好的解耦,但是基于HTTP請求的處理模式可謂與時代不符(與wicket相比就是過時了)。兩大原因如下:
* Struts并不是真正意義上的純粹面向對象,每個Action類定義了一個abstraction(抽取),但是abstraction是由HTTP協議的請求機制決定的,而并非面向對象的分析。
* 除非我們在java代碼中直接輸出HTML(當然除非我們瘋了),那么為了輸出HTML我們就要學習另外的主流技術,比如JSP和自定義tag。使用在JSP中使用tag并非易事,尤其是當我們把這項工作交給美工小組時,這會直接導致兩個結果:JSP代碼被他人作的一沓糊涂,或者是我們自己完成這項任務。
而Wicket的處理方式則不同,從整體來講應該說是更加優雅些。它采用面向對象的組件技術實現web與用戶的交互(這點有些如Swing)。在Wicket中的每一頁是由若干的使用組合設計模板生成的組件構成。頁面和組件各自渲染自己,并直接或者間接的與markup文件(標識文件,形式就像JSP)關聯。當HTTP請求到來時,這些請求被轉換、傳遞到組件上的相應事件中來,這一點與微軟的VS很相象。所以Wicket能夠解決struts體系中存在的問題:
* Wicket是完全面向對象的。我們可以利用組件的繼承性設計自己的應用。這里不需要為處理HTTP協議的請求/響應而作任何工作。
* Wicket所使用的markup文件與純粹的HTML很接近,所以容易上手使用。Wicket在markup文件中所引入的內容非常整潔,并符合XHTML標準。任何了解HTML的開發者都可以如編輯HTML文件那樣編輯Wicket的markup文件,就好似他并不知道這是Wicket的markup文件一樣。
三、HTTP請求處理
在Struts中,一個HTTP請求被接收后,Struts將在配置文件中查找request path和相應的Action類。如果這些已經被配置好了,它將將提取請求參數放入到ActionForm bean中,并執行一些驗證。然后HTTP請求、回應和ActionForm對象都將作為參數傳入到Action類中。從這點可以看出Action的開發者掌握著應用的方方面面:他們必須處理HTTP session,維護HTTP請求和session的屬性,并在action執行完時建立需要返回的信息,最后還要返回相應的ActionForward以使struts知道下一步在哪里。假如此時ActionForward將控制權交給了JSP頁面,開發者就要使用struts自定義的tag庫編寫JSP代碼。如此繁復的工作環節很容易出現錯誤,而且struts還需要三個位置保持一致:struts XML配置文件、java Action類、JSP自定義tag。
而在Wicket中,一個HTTP請求被接收后,Wicket將確認HTTP所請求的那個頁面和在這個頁面關聯的組件。如果請求的目的是form,Wicket將自動提取請求參數、驗證參數、進行一些預先規定好的類型轉換、設置form組件中的model(模式,這里用法與MVC中類似,但有不同)值;接著轉化請求為相應類型的事件、調用目標組件上的相應事件偵聽器,這樣就會導致事件處理代碼運行來執行業務邏輯;然后,事件處理器還將指定下一步頁面的位置,被指定的頁面將初始化(如果頁面從未被初始化的話)并自動渲染;渲染處理將按照順序訪問每個頁面組件,要求它們進行自我渲染。在markup文件中能夠組件僅通過名字與HTML元素進行映射。
Wicket出色的原因:
* 每個組件知道如何處理自己事件。因此我們只需要將組件放到頁面上,編寫事件處理器就行了。如果一個頁面中存在20個能引發事件的不同的組件,我們除了進行將它們添加到頁面上的工作外沒有別的工作。但如果在struts中,我們可能需要建立20個不同的Action類或者一個具有20個分支語句的Action類,并要在XML配置中逐一添加。
* Wicket帶給了我們考慮組件/事件重用的機會。而不用將注意力放到如何處理HTTP請求和回應上。
* 與struts相比使用Wicket會降低我們的代碼量,這正是重用組件帶來的益處。Wicket本身不使用任何的XML配置文件。只需要修改web容器的web.xml文件中的servlet聲明部分。
假如我們曾經編寫過Windows API、并用過Visual Basic或者Borland Delphi的話,下面的比較會更加讓人印象深刻。使用struts開發就像使用Windows API一樣:接收原始消息,解碼原始消息,然后再處理這些消息。由于Windows API是基于消息循環工作的,所以系統除了消息回應外不期望任何的返回值。
從另一方面看,Dephi在TApplication類中隱藏了Windows消息循環,使開發人員圍繞著TApplication類建立其他的類。原始的系統消息就這樣被Dephi內建類接收,被內建類解析并被確定其接納者。消息被轉換為一個事件,并被傳送到某個特定的對象。
如Windows應用程序一樣,Wicket應用也具有服務于文本和HTML模板的資源文件。從這點看,Wicket象用Delphi做桌面開發一樣被用來做web開發。
四、Servlet API和HTTP協議的抽取
Struts沒有隱藏Servlet API和HTTP協議的細節。為了使用Struts,我們必須樂于和HTTPServletRequest、HttpServletResponse 和HttpSession類打交道。并圍繞著請求和回應建立應用。這便是所有Model2 MVC wen框架與生俱來的弱點。
正如上面說的,Wicket隱藏了Servlet API和HTTP協議的細節。對于一些應用,我們甚至觸及不到這些細節。甚至對于非常復雜的應用,我們也僅使用適當的Wicket協議抽取類。而經常用到的是java組件類、POJO業務模型、純HTML標記文件。
五、狀態管理
使用Struts開發,我們將獲得全部的狀態管理權。這對于建立大規模的、高升級空間的、集群應用來講是很好的,因為我們將獲得對HttpSession上每件事物的控制權。但是對于中小型應用,我們將沒有緣由編寫一些額外的代碼。這樣將導致應用變得復雜和編寫費時。
在狀態管理上,Wicket可以作為一個不錯的選擇。Wicket框架默認代管所有的組件狀態。這對于中小型應用,在狀態管理上的代碼量幾乎為0。但是Wicket也提供了一些API使我們進行標準狀態管理和實現自己的狀態管理。這樣,即使是大型應用,我們也能夠全權掌握狀態管理。事實上,即使在使用Wicket編寫大型應用時,通常也是先讓Wicket代管所有的狀態,然后再慢慢的實現自己定義的狀態管理以提高應用性能。
六、配置
不言自明,Struts需要一個XML文件:定義對HTTP請求和響應的映射和所有的ActionForm對象等。這個文件可能非常大而且復雜。而新版本的Struts提供了將這個文件分解為多個模塊的方法,雖然這樣可以將模塊分類,但是這樣同樣要維護許多的小文件。
Wicket不需要配置文件。Wicket通過一個簡單的應用配置類或者通過編寫web容器的web.xml文件中Servlet init參數來完成程序的初始化。而HTTP請求到組件事件的映射、組件如何輸出HTML等被包含在了Wicket的應用邏輯里,從而極大地簡化了配置。
七、參考資料
http://wicket.sourceforge.net/
http://www.wicket-wiki.org.uk/wiki/index.php/Newuserguide
http://www.tkk7.com/tommyjian/archive/2007/06/10/123202.html
感謝Tommy Jian
為什么是Wicket?
如果您正在尋求使用Java開發Web應用程序,目前,您有很多的選擇。實際上,存在如此眾多的Web應用程序框架顯得有點搞笑。來自于互聯網一個博客站點的問題:您能說出多少Java Web應用框架的名字?他們展現的結果如下:
框架,到處都是框架,參看后面附帶的表格。
為什么要“重新發明輪子”?
從這個角度看,您對于“另一個Web應用程序框架有多好”這個問題總是耿耿于懷?確實,為什們要“重新發明輪子”呢?對這個古老的諺語的答復是:因為這一次可以使輪子更圓!
但是對于高質量的期待并不是構建Wicket框架的唯一動因。甚至有很多的觀點,認為沒有其他的Web工具集填補這一空白,而Wicket做到了。實際上,Wicket與上面提及的眾多框架不太一樣。
與Wicket最相近的或許是Tapestry和Echo,但是這種相似性也很有限。和Tapestry一樣,Wicket使用特定的HTML屬性來標識組件(Components)聲明,這可以方便使用一般的HTML編輯器進行文件編輯。和Echo一樣,Wicket擁有一流的組件模型。但是基于Wicket的應用程序和那些基于Tapestry和Echo的應用程序不一樣,這是因為從Wicket框架中兩方面都可以受益。您獲得了一流的組件模型和對HTML沒有干擾所帶來的益處。在很多情況下,這種復合的好處可以帶來非常重要的開發優勢。
理解了構建Wicket的動機有助于您理解為什么Wicket會表現的不一樣。
Echo
|
Cocoon
|
Millstone
|
OXF
|
Struts
|
SOFIA
|
Tapestry
|
WebWork
|
RIFE
|
Spring MVC
|
Canyamo
|
Maverick
|
JPublish
|
JATO
|
Folium
|
Jucas
|
Verge
|
Niggle
|
Bishop
|
Barracuda
|
Action Framework
|
Shocks
|
TeaServlet
|
wingS
|
Expresso
|
Bento
|
jStatemachine
|
jZonic
|
OpenEmcee
|
Turbine
|
Scope
|
Warfare
|
JMAA
|
Jaffa
|
Jacquard
|
Macaw
|
Smile
|
MyFaces
|
Chiba
|
JBanana
|
Jeenius
|
JWarp
|
Genie
|
Melati
|
Dovetail
|
Cameleon
|
JFormular
|
Xoplon
|
Japple
|
Helma
|
Dinamica
|
WebOnSwing
|
Nacho
|
Cassandra
|
Baritus
|
|
動機
目前存在的大多數Web框架對于服務端的狀態管理都僅僅提供了較弱的支持。
這就意味著在Web應用程序中存在著很多特殊的代碼來處理和維護繁復的狀態管理機制。雖然Wicket并不允許對服務端的狀態完全不考慮,但是它在狀態管理的簡便性和透明化方面做了很多的工作。
在Wicket中,所有服務端的狀態都被納入了自動的管理。您始終不需要直接使用HttpSession對象或者類似的封裝對象去存儲狀態信息。相反,狀態信息已經都與組件關聯起來,而在組件后端的數據模型都是傳統的Java對象(POJO)。Wicket在每個用戶會話期內維護著頁面的映射表(Map)。這個頁面映射表(以及每個一面內的組件層次)的目的在于使得框架隱藏了組件以及數據模型訪問的細節。您只需要處理簡單而熟悉的Java對象,而Wicket則處理諸如URL、會話期標識以及GET/POST請求的任務。
您接著也會發現這種結構良好的服務端狀態使得解決令人恐懼的“后退按鈕問題”變得十分的容易。實際上,針對頁面內組件數據模型的結構性變化帶來的數據過期,Wicket提供了通用而且健壯的解決方案,這個方案可以有效地對瀏覽器緩存頁面進行甄別和過期檢測。
最后,Wicket在設計的時候就考慮與諸如JDO和Hibernate的普通Java對象(POJO)序列化框架協同工作。這一點使得構建數據驅動的Web應用程序顯得非常簡單。
對于很多應用程序來說,必須在額外服務端狀態導致服務器負載增加和其帶來的好處之間進行權衡,服務端狀態管理可以降低開發成本、減少維護成本、加快對市場的響應時間以及生產高質量的軟件。這里提出的基本觀點是:軟件是十分昂貴、復雜的,而來自于E-machines和Dell的服務器則相對便宜。
在效率和生產性方面,Wicket對JSP的優越性則猶如Java語言對C語言一樣。您使用Wicket可以實現的功能使用JSP也都可以實現。甚至于在內存和CPU消耗方面效率也非常的高。但是使用JSP開發應用程序則需要耗費您更多的時間。最后,因為在JSP中進行狀態管理時使用了特別的方式,您可能發現不少的安全問題,也能看到到處蹦出來的錯誤。上面提及的大部分框架在這方面僅僅提供了有限的輔助。
大部分現存的框架需要特定的HTML代碼
JSP具有最深的侵入性,它允許將Java代碼直接嵌入Web頁面中。但是,上面列示的框架(除了Tapestry)都不同程度地針對HTML代碼引入了特殊的語法。
因為特殊語法改變了單純而簡單的HTML標記的實質,而Web設計者對于這一點是十分的熟悉,所以特殊語法并不是十分得人心。而且預覽、編輯和理解這種包含特殊語法的HTML也是十分困難的事情。
Wicket并沒引入任何新的HTML語法。相反,它通過Wicket命名空間(namespace)的標準兼容方式擴展了HTML,這完全兼容XHTML標準。這意味這您可以使用Macromedia Dreamweaver、Microsoft Frontpage、Word、Adobe Go Live以及其他現有的HTML編輯器來編輯您的Web頁面,并且可以和Wicket的組件協同工作。為了實現這個目標,Wicket始終在Wicket命名空間內使用單個id屬性(“wicket:id”)來標識那些需要框架進行特殊處理的標簽。如果您并不喜歡將有Wicket命名空間修飾的標簽和屬性展示給您的最終用戶,通過簡單的設置就可以完全消除它們,從而得到普通的與標準兼容的HTML代碼。
HTML中沒有特殊的語法意味著設計者可以直接模擬頁面,而您可以在開發的過程中直接使用這些頁面。向HTML頁面中添加Java組件就和設置組件的名稱屬性一樣簡單。然后,您可以直接將這些頁面交給Web設計人員,他們可以充滿信心地對其進行修改。
與其他的應用框架相比,Wicket在各方面的分離上提供更多的支持。Web設計者在對應用程序代碼不甚了解的情況下就可以編輯HTML(當然,他們不能移除組件名稱標簽,而且不能任意改變組件嵌套的層次,其他的事情都是可以的)。另一方面,編程者只需要關注與HTML混在一起的Java組件,而不需要了解頁面的最終陳現是什么樣子。通過這種職能清楚的工作方式,每個人都可以工作得更為順暢。
現存的框架易用性不好
目前存在的大部分框架工具在對象模型方面做得不夠。在一些框架中,對象模型是通過特定的XML來定義的。這些語法令人生厭,而且還需要特定的工具來編輯這些配置信息。由于這些框架并不是單一的Java類庫,您就不能使用包含編輯器、調試器和編譯器的IDE工具來編輯它們。
Wicket是化繁為簡的代表。在學習Wicket的過程中不需要了解任何配置文件。Wicket就是組件結構良好的普通的類庫。在Wicket中,您的Web應用程序與普通的Swing應用程序類似,而不是JSP應用程序。如果您熟悉Java(特別是如果您熟悉Swing),那么您就已經對Wicket有不少的了解了。
現存的框架可復用性不好
Tapestry和JSF雖然有可以重用的組件模型,但是您將發現與Wicket相比這并不是特別容易做到的事情。Wicket從設計之初就十分地注重組件的復用。在Wicket中,從現有的組件擴展編制諸如SignInPanel或者AddressForm的復合組件是十分簡單的事情。相對來說,針對瀏覽器的新特性編制新的組件也是十分容易的事情。Wicket的組件可以使用JAR格式進行打包,直接通過庫引用的方式就可以實現重用——不需要任何配置文件!
Web編程應該更關注編程樂趣!
這就是我編寫Wicket的個人方面的目標。現存的框架在實現開發的直接性、快捷性和簡易性方面真正地吸引我。我希望Wicket在Web應用程序開發的建議性和樂趣方面能夠邁出重要的一步。
目標
基于上面的這些動機,下面是Wicket的目標:
- 簡單(易用性、一致性、易懂性)
- 以POJO為核心
- 所有代碼均使用Java編寫
- 最小的概念域
- 避免過度地使用XML配置文件
- 全面解決“向后按鈕”問題
- 最大限度地類型安全以及編譯檢查
- 最大限度地分析運行時錯誤
- 對特定工具集的最小依賴
- 組件、容器和慣例始終保持一致性
- 復用
- 使用Wicket編制的組件具備高度的復用性
- 可復用的組件可以使用JAR文件發布
- 無侵入
- HTML以及其他標記性文件不會編程語法所干涉
- 在標記方面只有一個簡單的標簽
- 與任何普通的HTML編輯器兼容
- 圖形開發人員很容易識別并避免修改框架標簽
- 如果設計者不小心刪除了標簽,則很容易恢復它
- 安全
- 默認情況下代碼都是安全的
- 在頁面和URL中,只有顯式的聲明的鏈接才能公布數據狀態
- 具備最大限度類型安全邏輯
- 很容易集成到Java安全框架
- 富有效率,可伸縮性
- 在不犧牲其他目標的前提下保證效率和輕量級
- 可依附的優選會話期支持集群
- 通過與可分離模型的協作,會話復制形成的集群很容易實現和調整
- 完整
- Wicket團隊樂于為開發Java Web應用貢獻可用的且特性齊全的框架。核心框架是由本篇文檔的作者Jonathan Locke編寫和貢獻的。目前的團隊包括了很多經驗豐富的程序員,他們中的一些人還是上面提及的其他框架的開發者,他們也都擁有構建大型Java Web應用的經驗。我們對自己的處境十分的了解,因此也更能從框架使用者的角度來開發Wicket。
開發Wicket的一些網站和資料
1 Wicket
Wicket框架的大本營,在這里你可以通過Wiki了解更多關于Wicket開發的概念和技巧,還可以下載相關的資源,如Wicket核心包,Wicket的擴展包,還有Wicket自帶的例子。
http://gocom.primeton.com/modules/newbb/viewforum41.htm(本文作者主持的中文論壇)
http://wicket.sourceforge,net(這是Wicket在sourceforge的根據地)
http://www.wicketframework.org(這是Wicket的獨立域名)
2 Wicket-Stuff
因為Wicket作為一個Web框架,只可能提供最核心的功能,但是在實際的開發中,需要更多的控件以及輔助的功能,如與Hibernate的整合,數據分布列表控件等,Wicket-Stuff就是一個致力于開發Wicket擴展功能的站點,目前已經提供了以下的擴展功能:
v 整合Dojo
v 整合Hibernate的控件Hibernate (2.1 and 3) components
v 支持客戶端數據驗證的控件
v 支持Groovy腳本編程
v Velocity控件面板
v 整合Freemarker
v 整合JasperReports
v 整合TinyMCE這個Html編輯器
v 整合Yahoo Ajax UI控件
http://wicket-stuff.sourceforge.net/
3 Wicket-Quickstart
Wicket雖然入門門框不高,但是許多熱心的開發人員還是提供了許多詳細的教程,幫助開發人員學習如何在各種IDE環境下開發Wicket應用程序。
http://wicketframework.org/wicket-quickstart/index.htmlHtml
4 Wicket-Library
Wicket-Library也是一個類似于Wicket-Stuff的站點,它的目的也是為了提供更多的Wicket控件,為開發人員服務,但是目前并沒有提供什么有用的控件。
它的網站上提供了Wicket例子的在線演示,如果你不想在本機上安裝Tomcat,JDK等軟件,就可以在這個網站上看Wicket提供的例子。
http://www.wicket-library.com/
5 DataBinder
DataBinder是一個將Hibernate整合到Wicket中的一個擴展功能,對于那些以數據驅動為開發目的的Web程序,它是不二之選。
http://databinder.net/
6 Hibernate
Hibernate本身與Wicket并沒有關系,但是Wicket-Stuff和DataBinder都已經提供了Hibernate的擴展功能,所以把Hibernate也放入這個列表,方便大家使用Hibernate。
http://www.hibernate.org/
7 QWicket
QWicket是一些熱心的Wicket開發人員,為了讓更多的開發人員了解Wicket,所以提供了一個很完整的應用程序,它是Wicket世界中的Appfuse。
http://www.antwerkz.com/qwicket/
8 Wicket Bench
Wicket Bench是一個用來輔助Wicket進行開發的Eclipse插件工具。前面已經對它進行了詳細的介紹。
http://www.laughingpanda.org/mediawiki/index.php/Wicket_Bench
9 Mail-Archive
Mail-Archive本身不是一個與技術有關的網站,它是一個郵件組歸檔的站點,常用的郵件組在上面都有歸檔,如Jakarta小組的開源軟件,Wicket也在上面,還有許多,在上面可以查看許多Wicket的討論,非常的精彩。
你可以通過下面的網址直接訪問Mail-Archive網站上Wicket郵件組的歸檔:
http://www.mail-archive.com/wicket-user%40lists.sourceforge.net/
10 一些Blog
Wicket的開發人員和Wicket一些資深用戶將自己關于Wicket的開發經驗放在自己的Blog上,與大家共享:
v A Wicket Diary - Martijn Dashorst
v Chillenious! - Eelco Hillenius
v Jonathan - Jonathan Locke
v N8than - Nathan Hamblen
v Antwerkz - Justin Lee
v System Mobile - Nick Heudecker
v Geertjan - Geertjan Wielenga