中文亚洲AV片不卡在线观看 ,国产成人亚洲精品91专区手机,国产精品亚洲专区一区http://www.tkk7.com/wangxq/category/17202.html共同努力,共造輝煌!zh-cnThu, 08 Mar 2007 02:33:22 GMTThu, 08 Mar 2007 02:33:22 GMT60Struts測試之Mock Object測試http://www.tkk7.com/wangxq/articles/31124.html扭轉乾坤扭轉乾坤Fri, 17 Feb 2006 01:02:00 GMThttp://www.tkk7.com/wangxq/articles/31124.htmlhttp://www.tkk7.com/wangxq/comments/31124.htmlhttp://www.tkk7.com/wangxq/articles/31124.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/31124.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/31124.html閱讀全文

扭轉乾坤 2006-02-17 09:02 發(fā)表評論
]]>
Struts例解http://www.tkk7.com/wangxq/articles/12431.html扭轉乾坤扭轉乾坤Thu, 08 Sep 2005 06:46:00 GMThttp://www.tkk7.com/wangxq/articles/12431.htmlhttp://www.tkk7.com/wangxq/comments/12431.htmlhttp://www.tkk7.com/wangxq/articles/12431.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/12431.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/12431.html

]]>
轉載http://www.tkk7.com/wangxq/articles/10711.html扭轉乾坤扭轉乾坤Mon, 22 Aug 2005 09:43:00 GMThttp://www.tkk7.com/wangxq/articles/10711.htmlhttp://www.tkk7.com/wangxq/comments/10711.htmlhttp://www.tkk7.com/wangxq/articles/10711.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/10711.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/10711.html閱讀全文

扭轉乾坤 2005-08-22 17:43 發(fā)表評論
]]>
轉載"深入Struts 1.1 "http://www.tkk7.com/wangxq/articles/10527.html扭轉乾坤扭轉乾坤Fri, 19 Aug 2005 07:41:00 GMThttp://www.tkk7.com/wangxq/articles/10527.htmlhttp://www.tkk7.com/wangxq/comments/10527.htmlhttp://www.tkk7.com/wangxq/articles/10527.html#Feedback0http://www.tkk7.com/wangxq/comments/commentRss/10527.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/10527.html 深入Struts 1.1

王和全

2003 年 8 月 02 日

作為基于MVC模式的Web應用最經(jīng)典框架,Struts已經(jīng)正式推出了1.1版本,該版本在以往版本的基礎上,提供了許多激動人心的新功能。本文就將帶你走進Struts 1.1去深入地了解這些功能。

說明:希望本文的讀者能有一定的Struts使用基礎。

Model 2

Struts是基于Model 2之上的,而Model 2是經(jīng)典的MVC(模型-視圖-控制器)模型的Web應用變體,這個改變主要是由于網(wǎng)絡應用的特性--HTTP協(xié)議的無狀態(tài)性引起的。Model 2的目的和MVC一樣,也是利用控制器來分離模型和視圖,達到一種層間松散耦合的效果,提高系統(tǒng)靈活性、復用性和可維護性。在多數(shù)情況下,你可以將Model 2與MVC等同起來。

下圖表示一個基于Java技術的典型網(wǎng)絡應用,從中可以看出Model 2中的各個部分是如何對應于Java中各種現(xiàn)有技術的。


在利用Model 2之前,我們是把所有的表示邏輯和業(yè)務邏輯都集中在一起(比如大雜燴似的JSP),有時也稱這種應用模式為Model 1,Model 1的主要缺點就是緊耦合,復用性差以及維護成本高。

Struts 1.1 和Model 2

既然Struts 1.1是基于Model 2之上,那它的底層機制也就是MVC,下面是Struts 1.1中的MVC實現(xiàn)示意圖:


圖解說明:其中不同顏色代表MVC的不同部分:紅色(控制器)、紫色(模型)和綠色(視圖)

首先,控制器(ActionServlet)進行初始化工作,讀取配置文件(struts-config.xml),為不同的Struts模塊初始化相應的ModuleConfig對象。比如配置文件中的Action映射定義都保存在ActionConfig集合中。相應地有ControlConfig集合、FormBeanConfig集合、ForwardConfig集合和MessageResourcesConfig集合等。

提示:模塊是在Struts 1.1中新提出的概念,在稍后的內(nèi)容中我們將詳細介紹,你現(xiàn)在可以簡單地把模塊看作是一個子系統(tǒng),它們共同組成整個應用,同時又各自獨立。Struts 1.1中所有的處理都是在特定模塊環(huán)境中進行的。模塊的提出主要是為了解決Struts 1.0中單配置文件的問題。

控制器接收HTTP請求,并從ActionConfig中找出對應于該請求的Action子類,如果沒有對應的Action,控制器直接將請求轉發(fā)給JSP或者靜態(tài)頁面。否則控制器將請求分發(fā)至具體Action類進行處理。

在控制器調用具體Action的execute方法之前,ActionForm對象將利用HTTP請求中的參數(shù)來填充自己(可選步驟,需要在配置文件中指定)。具體的ActionForm對象應該是ActionForm的子類對象,它其實就是一個JavaBean。此外,還可以在ActionForm類中調用validate方法來檢查請求參數(shù)的合法性,并且可以返回一個包含所有錯誤信息的ActionErrors對象。如果執(zhí)行成功,ActionForm自動將這些參數(shù)信息以JavaBean(一般稱之為form bean)的方式保存在Servlet Context中,這樣它們就可以被其它Action對象或者JSP調用。

Struts將這些ActionForm的配置信息都放在FormBeanConfig集合中,通過它們Struts能夠知道針對某個客戶請求是否需要創(chuàng)建相應的ActionForm實例。

Action很簡單,一般只包含一個execute方法,它負責執(zhí)行相應的業(yè)務邏輯,如果需要,它也進行相應的數(shù)據(jù)檢查。執(zhí)行完成之后,返回一個ActionForward對象,控制器通過該ActionForward對象來進行轉發(fā)工作。我們主張將獲取數(shù)據(jù)和執(zhí)行業(yè)務邏輯的功能放到具體的JavaBean當中,而Action只負責完成與控制有關的功能。遵循該原則,所以在上圖中我將Action對象歸為控制器部分。

提示:其實在Struts 1.1中,ActionMapping的作用完全可以由ActionConfig來替代,只不過由于它是公共API的一部分以及兼容性的問題得以保留。ActionMapping通過繼承ActionConfig來獲得與其一致的功能,你可以等同地看待它們。同理,其它例如ActionForward與ForwardConfig的關系也是如此。

下圖給出了客戶端從發(fā)出請求到獲得響應整個過程的圖解說明。


下面我們就來詳細地討論一下其中的每個部分,在這之前,先來了解一下模塊的概念。

模塊

我們知道,在Struts 1.0中,我們只能在web.xml中為ActionServlet指定一個配置文件,這對于我們這些網(wǎng)上的教學例子來說當然沒什么問題,但是在實際的應用開發(fā)過程中,可能會有些麻煩。因為許多開發(fā)人員都可能同時需要修改配置文件,但是配置文件只能同時被一個人修改,這樣肯定會造成一定程度上的資源爭奪,勢必會影響開發(fā)效率和引起開發(fā)人員的抱怨。

在Struts 1.1中,為了解決這個并行開發(fā)的問題,提出了兩種解決方案:

  1. 多個配置文件的支持
  2. 模塊的支持

支持多個配置文件,是指你能夠為ActionServlet同時指定多個xml配置文件,文件之間以逗號分隔,比如Struts提供的MailReader演示例子中就采用該種方法。

																				
  <!-- Action Servlet Configuration -->
  <servlet>
	<servlet-name>action</servlet-name>
	<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
	<init-param>
		<param-name>config</param-name>
		<param-value>/WEB-INF/struts-config.xml, /WEB-INF/struts-config-registration.xml</param-value>
	</init-param> 
	<load-on-startup>1</load-on-startup>
  </servlet>


																		

這種方法可以很好地解決修改沖突的問題,不同的開發(fā)人員可以在不同的配置文件中設置自己的Action、ActionForm等等(當然不是說每個開發(fā)人員都需要自己的配置文件,可以按照系統(tǒng)的功能模塊進行劃分)。但是,這里還是存在一個潛在的問題,就是可能不同的配置文件之間會產(chǎn)生沖突,因為在ActionServlet初始化的時候這幾個文件最終還是需要合并到一起的。比如,在struts-config.xml中配置了一個名為success的<forward>,而在struts-config-registration.xml中也配置了一個同樣的<forward>,那么執(zhí)行起來就會產(chǎn)生沖突。

為了徹底解決這種沖突,Struts 1.1中引進了模塊(Module)的概念。一個模塊就是一個獨立的子系統(tǒng),你可以在其中進行任意所需的配置,同時又不必擔心和其它的配置文件產(chǎn)生沖突。因為前面我們講過,ActionServlet是將不同的模塊信息保存在不同的ModuleConfig對象中的。要使用模塊的功能,需要進行以下的準備工作:

1、為每個模塊準備一個配置文件

2、配置web.xml文件,通知控制器

決定采用多個模塊以后,你需要將這些信息告訴控制器,這需要在web.xml文件進行配置。下面是一個典型的多模塊配置:

																				
<init-param>
	<param-name>config</param-name>
	<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
	<param-name>config/customer</param-name> 
	<param-value>/WEB-INF/struts-config-customer.xml</param-value>
</init-param>
<init-param> 
	<param-name>config/order</param-name>
	<param-value>/WEB-INF/struts-config-order.xml</param-value>
</init-param>


																		

要配置多個模塊,你需要在原有的一個<init-param>(在Struts 1.1中將其對應的模塊稱為缺省模塊)的基礎之上,增加模塊對應的<init-param>。其中<param-name>表示為config/XXX的形式,其中XXX為對應的模塊名,<param-value>中還是指定模塊對應的配置文件。上面這個例子說明該應用有三個模塊,分別是缺省模塊、customer和order,它們分別對應不同的配置文件。

3、準備各個模塊所需的ActionForm、Action和JSP等資源

但是要注意的是,模塊的出現(xiàn)也同時帶來了一個問題,即如何在不同模塊間進行轉發(fā)?有兩種方法可以實現(xiàn)模塊間的轉發(fā),一種就是在<forward>(全局或者本地)中定義,另外一種就是利用org.apache.struts.actions.SwitchAction。

下面就是一個全局的例子:

																				
    ... 
    <struts-config>
	... 
	<global-forwards>
		<forward name="toModuleB"
			contextRelative="true"  
			path="/moduleB/index.do" 
		redirect="true"/>   
	... 
	</global-forwards>  
	...   
    </struts-config>

																		

可以看出,只需要在原有的path屬性前加上模塊名,同時將contextRelative屬性置為true即可。此外,你也可以在<action>中定義一個類似的本地<forward>。

																				
  <action-mappings>
	<!-- Action mapping for profile form -->
	<action path="/login" 
	type="com.ncu.test.LoginAction"  
	name="loginForm"     
	scope="request"      
	input="tile.userLogin"
	validate="true">     
	<forward name="success" contextRelative="true" path="/moduleA/login.do"/> 
	</action> 
  </action-mappings>

																		

如果你已經(jīng)處在其他模塊,需要轉回到缺省模塊,那應該類似下面這樣定義,即模塊名為空。

																				
<forward name="success" contextRelative="true" path="/login.do"/>


																		

此外,你也可以使用org.apache.struts.actions.SwitchAction,例如:

																				
    ...
    <action-mappings> 
	<action path="/toModule" 
	type="org.apache.struts.actions.SwitchAction"/>  
	...    
    </action-mappings>  
    ...

																		

ActionServlet

我們首先來了解MVC中的控制器。在Struts 1.1中缺省采用ActionServlet類來充當控制器。當然如果ActionServlet不能滿足你的需求,你也可以通過繼承它來實現(xiàn)自己的類。這可以在/WEB-INF/web.xml中來具體指定。

要掌握ActionServlet,就必須了解它所扮演的角色。首先,ActionServlet表示MVC結構中的控制器部分,它需要完成控制器所需的前端控制及轉發(fā)請求等職責。其次,ActionServlet被實現(xiàn)為一個專門處理HTTP請求的Servlet,它同時具有servlet的特點。在Struts 1.1中它主要完成以下功能:

  • 接收客戶端請求
  • 根據(jù)客戶端的URI將請求映射到一個相應的Action類
  • 從請求中獲取數(shù)據(jù)填充Form Bean(如果需要)
  • 調用Action類的execute()方法獲取數(shù)據(jù)或者執(zhí)行業(yè)務邏輯
  • 選擇正確的視圖響應客戶

此外,ActionServlet還負責初始化和清除應用配置信息的任務。ActionServlet的初始化工作在init方法中完成,它可以分為兩個部分:初始化ActionServlet自身的一些信息以及每個模塊的配置信息。前者主要通過initInternal、initOther和initServlet三個方法來完成。

我們可以在/WEB-INF/web.xml中指定具體的控制器以及初始參數(shù),由于版本的變化以及Struts 1.1中模塊概念的引進,一些初始參數(shù)被廢棄或者移入到/WEB-INF/struts-config.xml中定義。下面列出所有被廢棄的參數(shù),相應地在web.xml文件中也不鼓勵再使用。

  • application
  • bufferSize
  • content
  • debug
  • factory
  • formBean
  • forward
  • locale
  • mapping
  • maxFileSize
  • multipartClass
  • nocache
  • null
  • tempDir

ActionServlet根據(jù)不同的模塊來初始化ModuleConfig類,并在其中以XXXconfig集合的方式保存該模塊的各種配置信息,比如ActionConfig,F(xiàn)ormBeanConfig等。

初始化工作完成之后,ActionServlet準備接收客戶請求。針對每個請求,方法process(HttpServletRequest request, HttpServletResponse response)將被調用。該方法指定具體的模塊,然后調用該模塊的RequestProcessor的process方法。

																				
protected void process(HttpServletRequest request, 
		HttpServletResponse response) 
		throws IOException, ServletException {

	RequestUtils.selectModule(request, getServletContext());        
	getRequestProcessor(getModuleConfig(request)).process(request, response);
}

																		

RequestProcessor包含了Struts控制器的所有處理邏輯,它調用不同的processXXX方法來完成不同的處理。下表列出其中幾個主要的方法:

方法 功能
processPath 獲取客戶端的請求路徑
processMapping 利用路徑來獲得相應的ActionMapping
processActionForm 初始化ActionForm(如果需要)并存入正確的scope中
processActionCreate 初始化Action
processActionPerform 調用Action的execute方法
processForwardConfig 處理Action返回的ActionForward

ActionForm

對于ActionForm你可以從以下幾個方面來理解它:

  1. ActionForm表示HTTP窗體中的數(shù)據(jù),可以將其看作是模型和視圖的中介,它負責保存視圖中的數(shù)據(jù)供模型或者視圖使用。Struts 1.1文檔中把它比作HTTP和Action之間的防火墻,這體現(xiàn)了ActionForm具有的過濾保護的作用,只有通過ActionForm驗證的數(shù)據(jù)才能夠發(fā)送到Action處理。
  2. ActionForm是與一個或多個ActionConfig關聯(lián)的JavaBean,在相應的action的execute方法被調用之前,ActionForm會自動利用請求參數(shù)來填充自己(初始化屬性)。
  3. ActionForm是一個抽象類,你必須通過繼承來實現(xiàn)自己的類。

ActionForm首先利用屬性的getter和setter方法來實現(xiàn)初始化,初始化完畢后,ActionForm的validate方法被調用,你可以在其中來檢查請求參數(shù)的正確性和有效性,并且可以將錯誤信息以ActionErrors的形式返回到輸入窗體。否則,ActionForm將被作為參數(shù)傳給action的execute方法以供使用。

ActionForm bean的生命周期可以設置為session(缺?。┖蛂equest,當設置為session時,記得在reset方法中將所有的屬性重新設置為初始值。

由于ActionForm對應于HTTP窗體,所以隨著頁面的增多,你的ActionForm將會急速增加。而且可能同一類型頁面字段將會在不同的ActionForm中出現(xiàn),并且在每個ActionForm中都存在相同的驗證代碼。為了解決這個問題,你可以為整個應用實現(xiàn)一個ActionForm或者至少一個模塊對應于一個ActionForm。

但是,聚合的代價就是復用性很差,而且難維護。針對這個問題,在Struts 1.1中提出了DynaActionForm的概念。

DynaActionForm類

DynaActionForm的目的就是減少ActionForm的數(shù)目,利用它你不必創(chuàng)建一個個具體的ActionForm類,而是在配置文件中配置出所需的虛擬ActionForm。例如,在下表中通過指定<form-bean>的type為"org.apache.struts.action.DynaActionForm"來創(chuàng)建一個動態(tài)的ActionForm--loginForm。

																				
<form-beans>
	<form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">  
		<form-property name="actionClass" type="java.lang.String"/>
		<form-property name="username" type="java.lang.String"/>
		<form-property name="password" type="java.lang.String"/> 
	</form-bean> 
</form-beans>


																		

動態(tài)的ActionForm的使用方法跟普通的ActionForm相同,但是要注意一點。普通的ActionForm對象需要為每個屬性提供getter和setter方法,以上面的例子而言,我們需要提供getUsername() 和 setUsername()方法取得和設置username屬性,同樣地有一對方法用于取得和設置password屬性和actionClass屬性。

如果使用DynaActionForm,它將屬性保存在一個HashMap類對象中,同時提供相應的get(name) 和 set(name)方法,其中參數(shù)name是要訪問的屬性名。例如要訪問DynaActionForm中username的值,可以采用類似的代碼:

																				
String username = (String)form.get("username");


																		

由于值存放于一個HashMap對象,所以要記得對get()方法返回的Object對象做強制性類型轉換。正是由于這點區(qū)別,如果你在Action中非常頻繁地使用ActionForm對象,建議還是使用普通的ActionForm對象。

在Struts 1.1中,除了DynaActionForm以外,還提供了表單輸入自動驗證的功能,在包org.apache.struts.validator中提供了許多有用的類,其中最常見的就是DynaValidatorForm類。

DynaValidatorForm類

DynaValidatorForm是DynaActionForm的子類,它能夠提供動態(tài)ActionForm和自動表單輸入驗證的功能。和使用DynaActionForm類似,你必須首先在配置文件中進行配置:

																				
<form-beans>
	<form-bean name="loginForm" type="org.apache.struts.validator.DynaValidatorForm"> 
		<form-property name="actionClass" type="java.lang.String"/>     
		<form-property name="username" type="java.lang.String"/> 
		<form-property name="password" type="java.lang.String"/>  
	</form-bean>
</form-beans>


																		

同時要定義驗證的插件:

																				
  <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
	<set-property property="pathnames"  
	value="/WEB-INF/validator-rules.xml,  
	/WEB-INF/validation.xml"/>
  </plug-in>


																		

其中的validator.xml和validator-rules.xml分別表示驗證定義和驗證規(guī)則的內(nèi)容(可以合并在一起),比如針對上例中的DynaValidatorForm,我們有如下驗證定義(validator.xml):

																				
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE form-validation PUBLIC  
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN"  
"http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">
<!--    Validation Rules    $Id: validation.xml-->

<form-validation>  
<!-- ========== Default Language Form Definitions ===================== -->
<formset>  
	<form name="loginForm">     
		<field property="username" depends="required, minlength,maxlength"> 
			<arg0   key="prompt.username"/>          
			<arg1   key="${var:minlength}" name="minlength" resource="false"/>       
			<arg2   key="${var:maxlength}" name="maxlength" resource="false"/>              
			<var>                
				<var-name>maxlength</var-name>    
				<var-value>16</var-value>         
			</var>          
			<var>      
				<var-name>minlength</var-name>     
				<var-value>3</var-value>         
			</var>       
		</field>     
		<field property="password" depends="required, minlength,maxlength" bundle="alternate">          
			<arg0   key="prompt.password"/>   
			<arg1   key="${var:minlength}" name="minlength" resource="false"/>          
			<arg2   key="${var:maxlength}" name="maxlength" resource="false"/>  
			<var>              
				<var-name>maxlength</var-name>     
				<var-value>16</var-value>        
			</var>          
			<var>      
				<var-name>minlength</var-name> 
				<var-value>3</var-value>       
			</var>        
		</field>    
	</form>   
</formset>
</form-validation>

																		

從上述定義中,我們可以看到對于字段username有三項驗證:required, minlength, maxlength,意思是該字段不能為空,而且長度在3和16之間。而validator-rules.xml文件則可以采用Struts提供的缺省文件。注意在<form-bean>中定義的form是如何與validation.xml中的form關聯(lián)起來的。最后,要啟動自動驗證功能,還需要將Action配置的validate屬性設置為true。

																				

<action path="/login"  
type="com.ncu.test.LoginAction"
name="loginForm"          
scope="request"         
input="tile.userLogin"validate="true">


																		

此時,Struts將根據(jù)xml配置文件中的定義來檢驗表單輸入,并將不符合要求的錯誤信息輸出到頁面。但是你可能會想:這個功能雖然好,可是什么檢驗都跑到服務器端執(zhí)行,效率方面和用戶易用性方面是不是有些問題?你可能會懷念起那簡單的JavaScript客戶端驗證。

不用擔心,在Struts 1.1中也支持JavaScript客戶端驗證。如果你選擇了客戶端驗證,當某個表單被提交以后,Struts 1.1啟動客戶端驗證,如果瀏覽器不支持JavaScript驗證,則服務器端驗證被啟動,這種雙重驗證機制能夠最大限度地滿足各種開發(fā)者的需要。JavaScript驗證代碼也是在validator-rules.xml文件中定義的。要啟動客戶端驗證,你必須在相應的JSP文件中做如下設置:

  1. 為<html:form>增加onsubmit屬性
  2. 設置Javascript支持

下表中列出了一JSP文件的示例代碼,紅字部分為Javascript驗證所需代碼。

																				
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<table bgcolor="#9AFF9A" cellspacing="0" cellpadding="10" border="1" width="100%">
	<tr>
	<td> 
	<table cellspacing="0" cellpadding="0" border="0" width="100%"> 
	<tr bgcolor="#696969"> 
		<td align="center">     
		<font color="#FFFFFF">Panel 3: Profile</font>  
		</td>
		</tr> 
	<tr>  
		<td><br> 
		<html:errors/>  
		<html:form action="/login.do" focus="username"  onsubmit="return validateLoginForm(this);">  
		<html:hidden property="actionClass"/>   
		<center>      
		<table>      
			<tr>        
			<td>UserName:</td>   
			<td><html:text property="username" size="20"/></td> 
			</tr> 
			<tr>  
			<td>Password:</td>   
			<td><html:password property="password" size="20"/></td>    
			</tr>  
			<tr>  
			<td colspan=2><html:submit property="submitProperty" value="Submit"/></td>     
		</table>   
		</center>  
		</html:form> 
		<html:javascript formName="loginForm" dynamicJavascript="true" staticJavascript="false"/>  
	
	<script language="Javascript1.1" src="staticJavascript.jsp"></script>  
	</td> 
	</tr> 
	</table>
	</td>
	</tr>
</table>

																		

其中onsubmit的值為"return validateLoginForm(this);",它的語法為:

return validate + struts-config.xml中定義的form-bean名稱 + (this);

staticJavascript.jsp的內(nèi)容為:

																				
<%@ page language="java" %>
<%-- set document type to Javascript (addresses a bug in Netscape according to a web resource --%>
<%@ page contentType="application/x-javascript" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:javascript dynamicJavascript="false" staticJavascript="true"/>



																		

如果validator-rules.xml中定義的基本驗證功能不能滿足你的需求,你可以自己添加所需的驗證類型。

Action

我們通過繼承Action類來實現(xiàn)具體的執(zhí)行類。具體Action類的功能一般都在execute(以前是perform方法)方法中完成,其中主要涉及到以下幾個方面:

  1. 輔助ActionForm進行一些表單數(shù)據(jù)的檢查。
  2. 執(zhí)行必要的業(yè)務邏輯,比如存取數(shù)據(jù)庫,調用實體bean等。
  3. 更新服務器端的bean數(shù)據(jù),后續(xù)對象中可能會用到這些數(shù)據(jù),比如在JSP中利用bean:write來獲得這些數(shù)據(jù)。
  4. 根據(jù)處理結果決定程序的去處,并以ActionForward對象的形式返回給ActionServlet。

提示:由于在Action和ActionForm中都可以實現(xiàn)驗證方法,那么如何來安排它們之間的分工呢?一般來說,我們秉著MVC分離的原則,也就是視圖級的驗證工作放在ActionForm來完成,比如輸入不能為空,email格式是否正確,利用ValidatorForm可以很輕松地完成這些工作。而與具體業(yè)務相關的驗證則放入Action中,這樣就可以獲得最大ActionForm重用性的可能。

前面我們提到過,我們主張將業(yè)務邏輯執(zhí)行分離到單獨的JavaBean中,而Action只負責錯誤處理和流程控制。而且考慮到重用性的原因,在執(zhí)行業(yè)務邏輯的JavaBean中不要引用任何與Web應用相關的對象,比如HttpServletRequest,HttpServletResponse等對象,而應該將其轉化為普通的Java對象。關于這一點,可以參考Petstore中WAF框架的實現(xiàn)思路。

此外,你可能還注意到execute與perform的一個區(qū)別:execute方法簡單地擲出Exception異常,而perform方法則擲出ServletException和IOException異常。這不是說Struts 1.1在異常處理功能方面弱化了,而是為了配合Struts 1.1中一個很好的功能--宣稱式異常處理機制。

宣稱式異常處理

和EJB中的宣稱式事務處理概念類似,宣稱式異常處理其實就是可配置的異常處理,你可以在配置文件中指定由誰來處理Action類中擲出的某種異常。你可以按照以下步驟來完成該功能:

  1. 實現(xiàn)org.apache.struts.action.ExceptionHandler的子類,覆蓋execute方法,在該方法中處理異常并且返回一個ActionForward對象
  2. 在配置文件中配置異常處理對象,你可以配置一個全局的處理類或者單獨為每個Action配置處理類

下表就定義了一個全局的處理類CustomizedExceptionHandler,它被用來處理所有的異常。

																				
<global-exceptions> 
<exception 
	handler="com.yourcorp.CustomizedExceptionHandler" 
	key="global.error.message" 
	path="/error.jsp"    
	scope="request"    
	type="java.lang.Exception"/>
</global-exceptions>


																		

其中具體的參數(shù)含義,可以參考ExceptionHandler.java源文件。

taglib

講完了模型和控制器,接下來我們要涉及的是視圖。視圖的角色主要是由JSP來完成,從JSP的規(guī)范中可以看出,在視圖層可以"折騰"的技術不是很多,主要的就是自定義標記庫的應用。Struts 1.1在原有的四個標記庫的基礎上新增了兩個標記庫--Tiles和Nested。

其中Tiles除了替代Template的基本模板功能外,還增加了布局定義、虛擬頁面定義和動態(tài)頁面生成等功能。Tiles強大的模板功能能夠使頁面獲得最大的重用性和靈活性,此外可以結合Tiles配置文件中的頁面定義和Action的轉發(fā)邏輯,即你可以將一個Action轉發(fā)到一個在Tiles配置文件中定義的虛擬頁面,從而減少頁面的數(shù)量。比如,下表中的Action定義了一個轉發(fā)路徑,它的終點是tile.userMain,而后者是你在Tiles配置文件中定義的一個頁面。

																				
<!-- ========== Action Mapping Definitions ============================== -->
<action-mappings>  
<!-- Action mapping for profile form --> 
	<action path="/login"   
		type="com.ncu.test.LoginAction"      
		name="loginForm"    
		scope="request"     
		input="tile.userLogin"
		validate="true">     
		<forward name="success" path="tile.userMain"/>   
	</action> 
</action-mappings>

																		

Tiles配置文件:tiles-defs.xml

																				
<!DOCTYPE tiles-definitions PUBLIC 
"-//Apache Software Foundation//DTD Tiles Configuration//EN"       "http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>  
<!-- =======================================================  --> 
<!-- Master definitions                                       -->
<!-- =======================================================  --> 
<!-- Page layout used as root for all pages. --> 

<definition name="rootLayout" path="/tiles-layouts/rootLayout.jsp"> 
	<put name="titleString" value="CHANGE-ME"/>   
	<put name="topMenu" value="/tiles-components/topMenu.jsp"/> 
	<put name="leftMenu" value="/tiles-components/panel1.jsp"/>  
	<put name="body" value="CHANGE-ME"/>   
	<put name="footer" value="/tiles-components/footer.jsp"/> 
</definition> 

<!-- =======================================================  --> 
<!-- Page definitions 					-->  
<!-- =======================================================  --> 

<!-- User Login page --> 
<definition name="tile.userLogin" extends="rootLayout"> 
	<put name="titleString" value="User Login"/>  
	<put name="body" value="/src/userLogin.jsp"/> 
</definition>  
<!-- User Main page --> 
<definition name="tile.userMain" extends="rootLayout"> 
	<put name="titleString" value="User Main"/>  
	<put name="body" value="/src/userMain.jsp"/> 
</definition>
</tiles-definitions>

																		

而Nested標記庫的作用是讓以上這些基本標記庫能夠嵌套使用,發(fā)揮更大的作用。

Commons Logging 接口

所謂的Commons Logging接口,是指將日志功能的使用與日志具體實現(xiàn)分開,通過配置文件來指定具體使用的日志實現(xiàn)。這樣你就可以在Struts 1.1中通過統(tǒng)一的接口來使用日志功能,而不去管具體是利用的哪種日志實現(xiàn),有點于類似JDBC的功能。Struts 1.1中支持的日志實現(xiàn)包括:Log4J,JDK Logging API, LogKit,NoOpLog和SimpleLog。

你可以按照如下的方式來使用Commons Logging接口(可以參照Struts源文中的許多類實現(xiàn)):

																				
package com.foo;
// ...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//...
	public class Foo {    
	// ...    
	private static Log log = LogFactory.getLog(Foo.class);
	// ...    
	public void setBar(Bar bar) {       
		if (log.isTraceEnabled()) {         
			log.trace("Setting bar to " + bar);   
		}      
	this.bar = bar;   
	}
// ...
}

																		

而開啟日志功能最簡單的辦法就是在WEB-INF/classes目錄下添加以下兩個文件:

commons-logging.properties文件:

																				
# Note: The Tiles framework now uses the commons-logging package to output different information or debug statements. 
Please refer to this package documentation to enable it. The simplest way to enable logging is to create two files in 
WEB-INF/classes:
# commons-logging.properties
# org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
# simplelog.properties
# # Logging detail level,
# # Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
#org.apache.commons.logging.simplelog.defaultlog=trace
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog


																		

simplelog.properties文件:

																				
# Logging detail level,
# Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
org.apache.commons.logging.simplelog.defaultlog=fatal


																		

這里我們采用的日志實現(xiàn)是SimpleLog,你可以在simplelog.properties文件指定日志明細的級別:trace,debug,info,warn,error和fatal,從trace到fatal錯誤級別越來越高,同時輸出的日志信息也越來越少。而這些級別是和org.apache.commons.logging.log接口中的方法一一對應的。這些級別是向后包含的,也就是前面的級別包含后面級別的信息。



扭轉乾坤 2005-08-19 15:41 發(fā)表評論
]]>
web.xml詳解http://www.tkk7.com/wangxq/articles/9912.html扭轉乾坤扭轉乾坤Fri, 12 Aug 2005 03:32:00 GMThttp://www.tkk7.com/wangxq/articles/9912.htmlhttp://www.tkk7.com/wangxq/comments/9912.htmlhttp://www.tkk7.com/wangxq/articles/9912.html#Feedback1http://www.tkk7.com/wangxq/comments/commentRss/9912.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/9912.htmlweb.xml詳解:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="

xmlns:xsi="

version="2.4"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee  

   <servlet>
      <servlet-name>action</servlet-name>//定義Servlet的名稱。

      <servlet-

class>org.apache.struts.action.ActionServlet</servlet-class>
//Servlet的完整類名
//說明:<servlet>中的<servlet-name>子元素必須和<servlet-

mapping>中的<servlet-name>子元素匹配。本例表明ActionServlet負

責處理所有的以.do結尾的URL。
      <init-param>配置Servlet初始化參數(shù)。
         <param-name>config</param-name>
         <param-value>/WEB-INF/struts-config.xml</param-value>
      </init-param>
      <init-param>
         <param-name>debug</param-name>
         <param-value>3</param-value>
      </init-param>
      <init-param>
         <param-name>detail</param-name>
         <param-value>3</param-value>
      </init-param>
      <load-on-startup>0</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>action</servlet-name>
      <url-pattern>*.do</url-pattern>
   </servlet-mapping>
   <welcome-file-list>//配置歡迎文件清單
     <welcome-file>/form/index.jsp</welcome-file>
   </welcome-file-list>

說明:<welcome-file-list>元素中可以包含多個<welcome-file>子元

素,當Web容器調用Web應用的歡迎文件時,首先尋找第一個<welcome-

file>指定的文件。如果這個文件存在,將把這一個文件返回給客戶;

如果這個文件不存在,Web容器將依次尋找下一個歡迎文件,直到找到

為止;如果都不存在,服務器將向客戶返回“HTTP 404 Not Found”的

出錯信息。

   <error-page>//配置錯誤處理

     <error-code>404</error-code>
     <location>/form/errors.jsp</location>
   </error-page>
   <error-page>
     <error-code>500</error-code>
     <location>/form/errors.jsp</location>
   </error-page>
   <error-page>
     <exception-

type>javax.servlet.ServletException</exception-type>
     <location>/form/errors.jsp</location>
   </error-page>
   //配置Struts標簽庫
<taglib>

     <taglib-uri>/WEB-INF/struts-html.tld</taglib-

uri>
     <taglib-location>/WEB-INF/struts-

html.tld</taglib-location>
   </taglib>
   <taglib>
     <taglib-uri>/WEB-INF/struts-bean.tld</taglib-

uri>
     <taglib-location>/WEB-INF/struts-

bean.tld</taglib-location>
   </taglib>
   <taglib>
     <taglib-uri>/WEB-INF/struts-logic.tld</taglib

-uri>
     <taglib-location>/WEB-INF/struts-

logic.tld</taglib-location>
   </taglib>
  // <taglib>元素有兩個子元素:<taglib-uri>和<taglib-location>

。<taglib-uri>元素指定標簽庫的相對或者絕對URI地址,Web應用將根

據(jù)這一URI來訪問標簽庫;<taglib-location>元素指定標簽庫描述文件

在文件資源系統(tǒng)中的物理位置。

</web-app>

 



扭轉乾坤 2005-08-12 11:32 發(fā)表評論
]]>
struts-config.xml文件詳解http://www.tkk7.com/wangxq/articles/9886.html扭轉乾坤扭轉乾坤Fri, 12 Aug 2005 02:20:00 GMThttp://www.tkk7.com/wangxq/articles/9886.htmlhttp://www.tkk7.com/wangxq/comments/9886.htmlhttp://www.tkk7.com/wangxq/articles/9886.html#Feedback1http://www.tkk7.com/wangxq/comments/commentRss/9886.htmlhttp://www.tkk7.com/wangxq/services/trackbacks/9886.html小技巧。在文本文件中插入時間(F5)。
以下是較為完整的struts-config.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software

Foundation//DTD Struts Configuration 1.1//EN"

"<struts-config>
<!--配置應用所需要的數(shù)據(jù)源-->
   <data-sources>
   <data-source

type="org.apache.commons.dbcp.BasicDataSource">
     <set-property property="autoCommit"

value="true"/>
     <set-property property="description"

value="MySQL Data Source"/>
     <set-property property="driverClass"

value="com.mysql.jdbc.Driver"/>
     <set-property property="maxCount" value="10"/>
     <set-property property="minCount" value="2"/>
     <set-property property="user" value="root"/>
     <set-property property="password" value=""/>
     <set-property property="url"

value="jdbc:mysql://localhost:3306/ebooklib"/>
   </data-source>
<!--配置多個數(shù)據(jù)源,有key值作標識-->
 <data-source key="A" type="">
 </data-source>
 <data-source key="B" type="">
 </data-source>
   </data-sources>
<!-- 定義一個FORM,用來保存JSP提交的數(shù)據(jù)-->
<!-- 定義一個ActionForm Bean,名叫registerForm,它對應的類為

com.yourcompany.struts.form.RegisterForm-->  
   <form-beans>
      <form-bean name="registerForm"

type="com.yourcompany.struts.form.RegisterForm" />
   </form-beans>
<!--配置異常處理-->
   <global-exceptions>
     <exception
      key="global.error.invalidalogin"http://指定在

Resource Bundle中描述該異常的消息key
      path="/forms/errors.jsp"http://指定當異常發(fā)生時的

轉發(fā)路徑
      scope="request"http://指定ActionMessage實例的存放

范圍
     

type="netstore.framework.exceptions.InvalidLoginException"/>//

指所需處理的異常類的名字。
//bundle屬性制定Resource Bundle
 </global-exceptions>
  
   <global-forwards>
     <forward name="register" //轉發(fā)路徑的邏輯名
path="/forms/register.jsp">//制定轉發(fā)或重定向的URI
redirect屬性為true時,表示重定向操作;為false時,表示執(zhí)行請求

轉發(fā)操作。
</forward>
   </global-forwards>
   <action-mappings >
      <action
         attribute="registerForm"http://設置Action關聯(lián)的ActionForm

Bean在request或session范圍內(nèi)的屬性key,通過

request.getAttribute("registerForm")就可以返回該Bean的一個實例

。
//forword屬性指定轉發(fā)的URL路徑
         input="/forms/register.jsp"http://輸入表單的路徑,驗證失敗

的返回路徑
         name="registerForm"http://指定和Action關聯(lián)的ActionForm

Bean的名字,必須在<form-beans>中定義過。
         path="/register"http://指定訪問Action的路徑
  forward="register.jsp"http://指定和path匹配的請求轉發(fā)路徑

,但用戶請求的URI圍register.do,Struts框架將把請求轉發(fā)給

register.jsp
         scope="request"http://指定ActionForm Bean 的存在范圍
<!-- validate指定是否執(zhí)行表單驗證-->
validate="true"
        type="com.yourcompany.struts.action.RegisterAction"

><!-- type指定Action的完整類名-->
<!-- 定義forward,當Action里返回success時就調用下一個

successpage.jsp頁面-->        
<forward name="success" path="/forms/successpage.jsp" />
         <forward name="fail" path="/forms/failturepage.jsp"

/>
      </action>
   </action-mappings>
//配置ActionServlet
   <controller
    contentType="text/html;charset=UTF-8"http://指定響應結果的內(nèi)容

類型和字符編碼!
    locale="true"指定是否把locale對象保存到當前用戶的session中

,默認false
    processorClass="CustomRequestProcessor"http://指定負責處理請求

的java類的完整類名
/>
//用來配置Resource Bundle,Resource Bundle用來存放本地化的消息

文本     
   <message-resources

parameter="com.yourcompany.struts.ApplicationResources" //指定

Resource Bundle的消息資源的名。
/>
//配置Struts插件
   <plug-in

className="org.apache.struts.validator.ValidatorPulgIn">
     <set-property property="pathnames"

value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
   </plug-in>
  
</struts-config>

 



扭轉乾坤 2005-08-12 10:20 發(fā)表評論
]]>
主站蜘蛛池模板: 一级A毛片免费观看久久精品 | 成人免费福利电影| 91亚洲国产成人精品下载| 两性色午夜免费视频| 伊人久久精品亚洲午夜| 久久WWW免费人成—看片| 中文字幕精品亚洲无线码一区 | 麻豆亚洲AV成人无码久久精品| 性感美女视频在线观看免费精品| 亚洲人成免费电影| 久九九精品免费视频| 亚洲深深色噜噜狠狠网站| 99久久免费国产精品特黄| 亚洲熟妇无码一区二区三区导航| 最近最新中文字幕完整版免费高清| 国产精品高清视亚洲一区二区| 久久久久久久91精品免费观看| 亚洲国产成人精品无码区二本| 免费看一级做a爰片久久| 曰批全过程免费视频免费看| 亚洲综合另类小说色区| 午夜视频免费在线观看| 亚洲国产高清视频在线观看| 免费无码又爽又刺激高潮| 男人j进女人p免费视频| 亚洲乱码无码永久不卡在线| 最近在线2018视频免费观看| 亚洲欧美国产国产综合一区| 亚洲精品无码日韩国产不卡?V | 亚洲av成本人无码网站| 国产亚洲自拍一区| 97在线视频免费| 亚洲色大成网站WWW国产| 亚洲人成电影网站国产精品 | 久久久久国色AV免费观看性色| 亚洲1区2区3区精华液| 亚洲综合伊人久久综合| 在线视频精品免费| 青娱乐在线视频免费观看| 亚洲s色大片在线观看| 最新免费jlzzjlzz在线播放|