Struts和JSF/Tapestry都屬于表現(xiàn)層框架,這兩種分屬不同性質(zhì)的框架,后者是一種事件驅(qū)動(dòng)型的組件模型,而Struts只是單純的MVC模式框架,老外總是急吼吼說事件驅(qū)動(dòng)型就比MVC模式框架好,何以見得,我們下面進(jìn)行詳細(xì)分析比較一下到底是怎么回事?
首先事件是指從客戶端頁面(瀏覽器)由用戶操作觸發(fā)的事件,Struts使用Action來接受瀏覽器表單提交的事件,這里使用了Command模式,每個(gè)繼承Action的子類都必須實(shí)現(xiàn)一個(gè)方法execute。
在struts中,實(shí)際是一個(gè)表單Form對應(yīng)一個(gè)Action類(或DispatchAction),換一句話說:在Struts中實(shí)際是一個(gè)表單只能對應(yīng)一個(gè)事件,struts這種事件方式稱為application event,application event和component event相比是一種粗粒度的事件。
struts重要的表單對象ActionForm是一種對象,它代表了一種應(yīng)用,這個(gè)對象中至少包含幾個(gè)字段,這些字段是Jsp頁面表單中的input字段,因?yàn)橐粋€(gè)表單對應(yīng)一個(gè)事件,所以,當(dāng)我們需要將事件粒度細(xì)化到表單中這些字段時(shí),也就是說,一個(gè)字段對應(yīng)一個(gè)事件時(shí),單純使用Struts就不太可能,當(dāng)然通過結(jié)合JavaScript也是可以轉(zhuǎn)彎實(shí)現(xiàn)的。
而這種情況使用JSF就可以方便實(shí)現(xiàn),
<h:inputText id="userId" value="#{login.userId}"> <f:valueChangeListener type="logindemo.UserLoginChanged" /> </h:inputText> |
#{login.userId}表示從名為login的JavaBean的getUserId獲得的結(jié)果,這個(gè)功能使用struts也可以實(shí)現(xiàn),name="login" property="userId"
關(guān)鍵是第二行,這里表示如果userId的值改變并且確定提交后,將觸發(fā)調(diào)用類UserLoginChanged的processValueChanged(...)方法。
JSF可以為組件提供兩種事件:Value Changed和 Action. 前者我們已經(jīng)在上節(jié)見識(shí)過用處,后者就相當(dāng)于struts中表單提交Action機(jī)制,它的JSF寫法如下:
<h:commandButton id="login" commandName="login"> <f:actionListener type=”logindemo.LoginActionListener” /> </h:commandButton> |
從代碼可以看出,這兩種事件是通過Listerner這樣觀察者模式貼在具體組件字段上的,而Struts此類事件是原始的一種表單提交Submit觸發(fā)機(jī)制。如果說前者比較語言化(編程語言習(xí)慣做法類似Swing編程);后者是屬于WEB化,因?yàn)樗莵碜訦tml表單,如果你起步是從Perl/PHP開始,反而容易接受Struts這種風(fēng)格。