Struts和JSF/Tapestry都屬於表現層框架
這兩種分屬不同性質的框架
後者是一種事件驅動型的組件模型
而Struts只是單純的MVC模式框架
老外總是急吼吼說事件驅動型就比MVC模式框架好
何以見得
我們下面進行詳細分析比較一下到底是怎麼回事?
首先事件是指從客戶端頁面(浏覽器)由用戶操作觸發的事件
Struts使用Action來接受浏覽器表單提交的事件
這裡使用了Command模式
每個繼承Action的子類都必須實現一個方法execute
在Struts中
實際是一個表單Form對應一個Action類(或DispatchAction)
換一句話說
在Struts中實際是一個表單只能對應一個事件
Struts這種事件方式稱為application event
application event和Component event相比是一種粗粒度的事件
Struts重要的表單對象ActionForm是一種對象
它代表了一種應用
這個對象中至少包含幾個字段
這些字段是Jsp頁面表單中的input字段
因為一個表單對應一個事件
所以
當我們需要將事件粒度細化到表單中這些字段時
也就是說
一個字段對應一個事件時
單純使用Struts就不太可能
當然通過結合JavaScript也是可以轉彎實現的
而這種情況使用JSF就可以方便實現
<h:inputText id=
userId
value=
#{login
userId}
>
<f:valueChangeListener type=
logindemo
UserLoginChanged
/>
</h:inputText>
#{login
userId}表示從名為login的JavaBean的getUserId獲得的結果
這個功能使用struts也可以實現
name=
login
property=
userId
關鍵是第二行
這裡表示如果userId的值改變並且確定提交後
將觸發調用類UserLoginChanged的processValueChanged(
)方法
JSF可以為組件提供兩種事件
Value Changed和 Action
前者我們已經在上節見識過用處
後者就相當於struts中表單提交Action機制
它的JSF寫法如下
<h:commandButton id=
login
commandName=
login
>
<f:actionListener type=
logindemo
LoginActionListener
/>
</h:commandButton>
從代碼可以看出
這兩種事件是通過Listerner這樣觀察者模式貼在具體組件字段上的
而Struts此類事件是原始的一種表單提交Submit觸發機制
如果說前者比較語言化(編程語言習慣做法類似Swing編程)
後者是屬於WEB化
因為它是來自Html表單
如果你起步是從Perl/PHP開始
反而容易接受Struts這種風格
基本配置 Struts和JSF都是一種框架
JSF必須需要兩種包JSF核心包
JSTL包(標簽庫)
此外
JSF還將使用到Apache項目的一些commons包
這些Apache包只要部署在你的服務器中既可
JSF包下載地址
選擇其中Reference Implementation
JSTL包下載在 /downloads_taglibs
standard
cgi
所以
從JSF的驅動包組成看
其開源基因也占據很大的比重
JSF是一個SUN伙伴們工業標准和開源之間的一個混血兒
上述兩個地址下載的jar合並在一起就是JSF所需要的全部驅動包了
與Struts的驅動包一樣
這些驅動包必須位於Web項目的WEB
INF/lib
和Struts一樣的是也必須在web
xml中有如下配置
<web
app>
<servlet>
<servlet
name>Faces Servlet</servlet
name>
<servlet
class>javax
faces
webapp
FacesServlet</servlet
class>
<load
on
startup>
</load
on
startup>
</servlet>
<servlet
mapping>
<servlet
name>Faces Servlet</servlet
name>
<url
pattern>*
faces</url
pattern>
</servlet
mapping>
</web
app>
這裡和Struts的web
xml配置何其相似
簡直一模一樣
正如Struts的struts
config
xml一樣
JSF也有類似的faces
config
xml配置文件
<faces
config>
<navigation
rule>
<from
view
id>/index
jsp</from
view
id>
<navigation
case>
<from
outcome>login</from
outcome>
<to
view
id>/welcome
jsp</to
view
id>
</navigation
case>
</navigation
rule>
<managed
bean>
<managed
bean
name>user</managed
bean
name>
<managed
bean
class>rejsf
UserBean</managed
bean
class>
<managed
bean
scope>session</managed
bean
scope>
</managed
bean>
</faces
config>
在Struts
config
xml中有ActionForm Action以及Jsp之間的流程關系
在faces
config
xml中
也有這樣的流程
我們具體解釋一下Navigation
在index
jsp中有一個事件
<h:commandButton label=
Login
action=
login
/>
Action的值必須匹配form
outcome值
上述Navigation配置表示
如果在index
jsp中有一個login事件
那麼事件觸發後下一個頁面將是welcome
jsp
JSF有一個獨立的事件發生和頁面導航的流程安排
這個思路比struts要非常清晰
managed
bean類似Struts的ActionForm
正如可以在struts
config
xml中定義ActionForm的scope一樣
這裡也定義了managed
bean的scope為session
但是如果你只以為JSF的managed
bean就這點功能就錯了
JSF融入了新的Ioc模式/依賴性注射等技術
Ioc模式 對於Userbean這樣一個managed
bean
其代碼如下
public class UserBean {
private String name;
private String password;
// PROPERTY: name
public String getName() { return name; }
public void setName(String newValue) { name = newValue; }
// PROPERTY: password
public String getPassword() { return password; }
public void setPassword(String newValue) { password = newValue; }
}
<managed
bean>
<managed
bean
name>user</managed
bean
name>
<managed
bean
class>rejsf
UserBean</managed
bean
class>
<managed
bean
scope>session</managed
bean
scope>
<managed
property>
<property
name>name</property
name>
<value>me</value>
</managed
property>
<managed
property>
<property
name>password</property
name>
<value>secret</value>
</managed
property>
</managed
bean>
faces
config
xml這段配置其實是將
me
賦值給name
將secret賦值給password
這是采取Ioc模式中的Setter注射方式
Backing Beans 對於一個web form
我們可以使用一個bean包含其涉及的所有組件
這個bean就稱為Backing Bean
Backing Bean的優點是
一個單個類可以封裝相關一系列功能的數據和邏輯
說白了
就是一個Javabean裡包含其他Javabean
互相調用
屬於Facade模式或Adapter模式
對於一個Backing Beans來說
其中包含了幾個managed
bean
managed
bean一定是有scope的
那麼這其中的幾個managed
beans如何配置它們的scope呢?
<managed
bean>
<managed
property>
<property
name>visit</property
name>
<value>#{sessionScope
visit}</value>
</managed
property>
這裡配置了一個Backing Beans中有一個setVisit方法
將這個visit賦值為session中的visit
這樣以後在程序中我們只管訪問visit對象
從中獲取我們希望的數據(如用戶登陸注冊信息)
而visit是保存在session還是application或request只需要配置既可
UI界面 JSF和Struts一樣
除了JavaBeans類之外
還有頁面表現元素
都是是使用標簽完成的
Struts也提供了struts
faces
tld標簽庫向JSF過渡
使用Struts標簽庫編程復雜頁面時
一個最大問題是會大量使用logic標簽
這個logic如同if語句
一旦寫起來
搞的JSP頁面象俄羅斯方塊一樣
但是使用JSF標簽就簡潔優美
<jia:navigatorItem name=
inbox
label=
InBox
icon=
/images/inbox
gif
action=
inbox
disabled=
#{!authenticationBean
inboxAuthorized}
/>
如果authenticationBean中inboxAuthorized返回是假
那麼這一行標簽就不用顯示
多干淨利索!
先寫到這裡
我會繼續對JSF深入比較下去
如果研究過Jdon框架的人
可能會發現
Jdon框架的jdonframework
xml中service配置和managed
bean一樣都使用了依賴注射
看來對Javabean的依賴注射已經迅速地成為一種新技術象征
如果你還不了解Ioc模式
趕緊補課
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28617.html