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.blogjava.net/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