struts2學習筆記

1. 類型轉換:
	
	* 從頁面中獲取對應的內容
		
		* 在動作類action中,聲明與頁面中表單name屬性的值同名的屬性
		* 提供get和set方法
		* struts2框架就會通過反射機制,從頁面中獲取對應的內容
		
	* struts2框架不能把頁面中獲取到的字符串類型轉換成任何類型
	
	* 當struts2框架不能把頁面中獲取到的字符串類型進行轉換時,就需要自定義類型轉換器
	
	* 自定義類型轉換器:
		
		* 要麼實現TypeConverter接口或者繼承TypeConverter接口的某個實現類,我們繼承DefaultTypeConverter類
		
		* 重寫convertValue(Object value, Class toType){}方法
		
			* 參數"value":要轉換的值
			* 參數"toType":要轉換的類型
			
		* 具體代碼實現:
			if(value==null){
				return false;
			}
			
			if(toType==null){
				return false;
			}
			
			if(toType!=java.util.Date.class){
				return false;
			}
			
			if(value instanceof java.lang.String[]){
				String [] str = (String[])value;
				
				if(str[0]!=null&&str[0].length()>0){
					
					try {
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
						
						return sdf.parse(str[0]);
						
					} catch (ParseException e) {
						/*
						 *  在struts2框架裏,自定義的類型轉換器,
						 *  如果我們不手動拋出異常,struts2框架只捕獲異常,但是並不拋出。
						 *  所以框架就會認爲類型轉換器轉換成功,轉向成功頁面。
						 */
						throw new RuntimeException(e);
						
					}
				}
			}
		
		* 兩種註冊方式:
			* 基於字段的(局部)
				
				* 在動作類action同目錄下,創建一個名爲"UserAction-conversion.properties"的資源文件
					* UserAction爲動作類action的名稱
					* "-conversion.properties"是固定寫法
				
				* 其內容配置如下:
					createTime=cn.itcast.converter.DateConverter
				
			* 基於類的(全局)
				
				* 在src目錄下,創建一個名爲"xwork-conversion.properties"的資源文件
					* 該資源文件的名稱是固定的
				
				* 其內容配置如下:
					java.util.Date=cn.itcast.converter.DateConverter
		
		* 如果在頁面中輸入一個不正確的值的時候,不手動拋出異常,頁面依然轉向成功頁面
			/*
			 *  在struts2框架裏,自定義的類型轉換器,
			 *  如果我們不手動拋出異常,struts2框架只捕獲異常,但是並不拋出。
			 *  所以框架就會認爲類型轉換器轉換成功,轉向成功頁面。
			 */
		
		* 配置修改錯誤提示信息爲中文
			
			* 在動作類action同目錄下,創建一個名爲"converter.properties"的資源文件
			
			* 該資源文件配置如下:
				
				* 針對所有字段:
					xwork.default.invalid.fieldvalue=類型轉換失敗 "{0}".
				
				* 針對某個字段:
					invalid.fieldvalue.createTime=出生日期轉換失敗
			
			* 在struts.xml文件進行配置:
				<constant name="struts.custom.i18n.resources" 
						value="cn.itcast.converter.converter">
				</constant>
		
2. struts2框架的文件上傳:
	* 單文件上傳:
		* 在動作類action中聲明相關屬性:
			* 在動作類action中,要聲明與頁面中表單name屬性同名的屬性,同名的屬性的類型時File類型;
			* 在動作類action中,要聲明[同名的屬性]ContentType,類型時String類型;
			* 在動作類action中,要聲明[同名的屬性]FileName,類型時String類型
			* 給所有屬性提供get和set方法
		* 在業務方法中,處理文件上傳:
			* 獲取要上傳文件的路徑,保存的位置
			* 在目標文件夾內,創建一個與上傳文件同名的文件
			* 通過FileUtils工具類提供copyFile()方法,將臨時文件內容拷貝到目標文件夾下的那個同名的文件
		* 設置上傳文件的總大小
			* 在struts.xml文件中,<constant name="struts.multipart.maxSize" value="2097152000"></constant>
		* 設置上傳文件的大小、類型和擴展名:
			* 在自定義的配置文件中,在action標籤下:
				<!-- 配置攔截器的參數,這裏是文件上傳攔截器 -->
				<interceptor-ref name="defaultStack">
	              	<!-- 
	              		配置文件上傳攔截器的參數
	              			* 與定義參數的順序無關
	              			* 允許的類型(allowedTypes)和允許的擴展名(allowedExtensions)必須保持一致
	              	 -->
	              	<!-- 
	              		* 配置上傳文件的大小
	              			* struts.xml文件中配置的是上傳文件的總大小
	              			* 這裏配置的是上傳文件的單個大小
	              	 -->
	              	<param name="fileUpload.maximumSize">20971520</param>
	              	<!-- 配置上傳文件允許的類型,如果配置多個值的話,用","隔開 -->
	              	<param name="fileUpload.allowedTypes">text/plain,application/msword</param>
	              	<!-- 配置上傳文件的擴展名,如果配置多個值的話,用","隔開 -->
	              	<param name="fileUpload.allowedExtensions">.txt</param>
	            </interceptor-ref>
	         * 自定義上傳文件的錯誤提示信息:
	         	* 在動作類action同目錄下,創建一個名爲fileuploadmessage.properties資源文件(名爲自定義)
	         	* 改資源文件配置如下:
	         		struts.messages.error.uploading=Error uploading: {0}
					struts.messages.error.file.too.large=File too large: {0} "{1}" "{2}" {3}
					struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3}
					struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
		
		
	* 多文件上傳:
		* 所有流程於配置都與單文件上傳一致。
		* 需要注意的是:
			* 在頁面中,雖然是多文件上傳,但是頁面中表單的name屬性的值必須保持一致;
			* 在動作類action中聲明的相關屬性,類型改成數組;
			* 在業務方法中,相關處理流程改成單文件上傳的循環。
		
3. struts2手動驗證:
	* 首先要從頁面中獲取對應的標籤name屬性的值,在動作類action中聲明同名的屬性,提供get和set方法
	
	* 要繼承ActionSupport類或者實現Validateable接口
	
	* 重寫Validateable接口的validate()方法
		* 前提是:要保證setUsername()、validate()、login()方法要按照這個先後順序執行
	
	* 如果登錄失敗,如何處理:
		* this.addFieldError( key, value);
			* key:錯誤提示字段
			* value:錯誤提示信息
	
	* 什麼時候纔是驗證通過?
		* 驗證通過:1、map集合不存在;2、map集合存在併爲空
		* 驗證不通過:map集合存在並且不爲空
	
	* 分析需求:
		* 用戶名不能爲null ,""
		* 密碼不能爲null, "" ,並且密碼的長度6-12之間 
	
	* 針對所有業務方法進行驗證還是針對某個指定業務方法進行驗證?
		* 重寫的validate()方法,針對所有業務方法進行驗證
		* 重寫的validate()方法加上要驗證的指定的業務方法名(業務方法名的首字母大寫),實現針對某個指定的業務方法進行驗證
			* 爲什麼要這樣進行拼接?因爲struts2框架底層拼接,如果不這樣寫,底層就找不到對應方法名
	
struts2框架驗證(xml方式):
	* 首先要從頁面中獲取對應的標籤name屬性的值,在動作類action中聲明同名的屬性,提供get和set方法
	
	* 創建一個xml格式驗證文件:
		* 命名方式:ActionClassName-validation.xml,ActionClassName指的是動作類action的名稱
		* <validators>標籤:根元素
		* field:指定action中要校驗的屬性,實際上就是頁面中表單的name屬性的值
			* name:指定頁面中表單的name屬性的值
		* field-validator:指定驗證規則
			* type:指定驗證規則名稱,
					struts2框架提供的驗證規則放在xwork-core-xxx.jar
					下的com\opensymphony\xwork2\validator\validators
					的default.xml配置文件。
		* param:向底層的驗證規則傳遞的參數
		* message:驗證失敗時,提供的錯誤提示信息
	
	* 如果要對指定方法進行驗證的話:
		* xml驗證文件的命名方式:ActionClassName-ActionName-validation.xml,
								ActionName對應的是struts.xml文件對應的action標籤的name屬性的值
	
	
4. 如何自定義攔截器:
	* 所有的攔截器都需要實現Interceptor接口或者繼承Interceptor接口的擴展實現類
	
	* 要重寫init()、intercept()、destroy()方法
	
		* init()是在struts2框架運行時執行,在攔截器的生命週期中只執行一次,可以做必要的內容的初始化工作
		
		* intercept(),是每一次請求就執行一次,做相關處理工作。
		
			* intercept()方法接收一個ActionInvocation接口的實例
			
			* 通過這個接口的實例,可以獲取以下內容
			:
				//cn.itcast.aop.UserAction@15b5783,動作類的對象
				System.out.println("invocation.getAction() : "+invocation.getAction());
				
				//cn.itcast.aop.UserAction@15b5783,與invocation.getAction()方法獲取的是同一的對象
				System.out.println("invocation.getProxy().getAction() : "+invocation.getProxy().getAction());
				
				//userAction_save,自定義配置文件中的action標籤的name屬性的值
				System.out.println("invocation.getProxy().getActionName() : "+invocation.getProxy().getActionName());
				
				//save,對應動作類指定要執行的方法名
				System.out.println("invocation.getProxy().getMethod() : "+invocation.getProxy().getMethod());
				
				//	/aop,自定義配置文件中的package標籤的namespace屬性的值
				System.out.println("invocation.getProxy().getNamespace() : "+invocation.getProxy().getNamespace());
				
		* destroy()是在攔截器銷燬前執行,在攔截器的聲明週期中只執行一次。
		
	* 在struts.xml配置文件中,進行註冊
		* 在配置文件中的package標籤下,進行相關配置:
		
		<interceptors>
			<!-- 聲明自定義的攔截器 -->
			<interceptor name="expessionInterceptor" class="cn.itcast.aop.ExpessionInterceptor" />
			
			<!-- 聲明自定義攔截器棧 -->
			<interceptor-stack name="expessionStack">
                <interceptor-ref name="defaultStack"/>
                
                <!-- 配置使用自定義攔截器 -->
                <interceptor-ref name="expessionInterceptor"/>
                
            </interceptor-stack>
		</interceptors>
		
		<!-- 配置修改struts2框架運行時,默認執行的是自定義攔截器棧 -->
		<default-interceptor-ref name="expessionStack" />
	
5. 模型驅動:
	* 要從頁面中獲取表單元素的值,需要在動作類中聲明與頁面元素同名的屬性。導致動作類中既有javabean又有業務方法。
	
	* 將javabean和業務方法進行分離:
		* 將重新創建一個javabean,將javabean的內容放置其中。
		* 動作類action中只留業務方法
	
	* 在動作類中聲明的javabean無法從頁面中獲取同名的屬性
	
	* 需要使用struts2框架提供"ModelDriven(模型驅動)"
		
		* 實現ModelDriven這個接口
		
		* 重寫getModel()方法,返回該javabean的實例
		
		* 代碼如下:
			public class UserAction extends ActionSupport implements ModelDriven<User> {

				private User user = new User();
				
				public User getModel() {
					return user;
				}
			
				public String add(){
					System.out.println("UserAction ************* add()");
					return "add";
				}
				
				public String save(){
					System.out.println("UserAction ************* save()");
					
					return "success";
				}
			}
		
		* 模型驅動的原理:
			
			* 在不使用模型驅動的時候,之所以在動作類中獲取不到對應的屬性的原因:
				* 在ValueStack中沒有對應javabean的所有屬性
				
			* 模型驅動的作用,就是將javabean的實例壓入對象棧的棧頂,從而可以獲取到對應的屬性的值


6. 頁面回顯技術:
	* 通過模型驅動,在動作類action中,可以獲取到頁面中元素的值
	
	//方法一
	* 通過javabean實例的set()方法,將新的內容set到javabean中,從而放置在頁面對應元素中
		user.setUsername(newUser.getUsername());
		user.setTel(newUser.getTel());
		user.setDes(newUser.getDes());
	
	//方法二
	* 首先將值棧中,舊的javabean的內容,刪除掉
	* 然後將新的內容壓入到值棧中的棧頂
		ValueStack valueStack = ServletActionContext.getContext().getValueStack();
		valueStack.pop();
		valueStack.push(newUser);


7. 處理表單重複提交:
	
	* 在頁面中增加一個隱藏域:<s:token></s:token>
	
	* 創建一個struts.xml的配置文件,具體配置如下:
		<!-- 配置默認執行的攔截器棧,增加令牌攔截器 -->
		<interceptors>
			<interceptor-stack name="tokenStack">
				<interceptor-ref name="defaultStack" />
				<interceptor-ref name="token" >
					<!-- 配置令牌攔截器,攔截的方法名,如果配置多個方法時,用","隔開 -->
					<param name="includeMethods">save,update</param>
				</interceptor-ref>
			</interceptor-stack>
		</interceptors>
		
		<default-interceptor-ref name="tokenStack" />
	
	* 在struts.xml配置文件中,增加一個result結果類型:
		<!-- 配置表單重複提交後,要轉向到的頁面 -->
		<result name="invalid.token">/model/error.jsp</result>
	
	* 在表單重複提交後,要轉向到的頁面中通過<s:actionerror>獲取struts2框架底層提供錯誤提示信息
	
	* 將struts2框架底層提供錯誤提示信息改成中文:
		
		* 在與動作類action同級目錄下,創建名爲"token.properties"的資源文件,文件內容如下:
			struts.messages.invalid.token=表單重複提交,請刷新後重試!

			
						
		


發佈了14 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章