Struts2基礎--Struts2(你必須要懂得基礎)
阿新 • • 發佈:2019-02-01
1.輸入驗證
①概念:針對使用者在表單中輸入的資料進行檢查
②分類
[1]客戶端驗證:JavaScript
[2]伺服器端驗證:Servlet/Action
(1)宣告式驗證:通過在配置檔案中指定驗證規則來檢查使用者輸入資料
(2)程式設計式驗證:通過編寫程式碼來檢查使用者輸入資料
2.HelloWorld
①Action類:需要實現ValidationAware介面,通過繼承ActionSupport實現
②在Struts2配置檔案中提供name=input的result
③引入驗證規則配置檔案
[1]參考:LibrarySupport\struts-2.3.15.3\apps\struts2-blank\WEB-INF\src\java\example\Login-validation.xml檔案
[2]格式:Action類簡單類名-validation.xml
[3]位置:和目標Action類在同一個包下
3.宣告式驗證的基本原理[瞭解]
①驗證規則背後的驗證器類
[1]驗證規則的宣告
xwork-core-2.3.15.3.jar\com.opensymphony.xwork2.validator.validators\default.xml檔案
[2]驗證器類
②驗證規則中指定的引數如何傳遞給驗證器物件?
通過驗證器物件的setXxx()方法傳入
③驗證訊息如何解析的?
[1]關鍵:錯誤訊息中可以包含OGNL表示式,例如:${min}或${max}
[2]原理:解析錯誤訊息時,臨時將驗證器物件壓入棧頂,解析完成後從棧頂彈出
4.驗證訊息國際化
①準備國際化資原始檔
②在Struts2配置檔案中指定國際化資原始檔的基名
③在message標籤的key屬性中指定國際化資原始檔中的鍵即可
5.simple主題顯示錯誤訊息
①使用s:fielderror標籤顯示錯誤訊息
②可以通過修改s:fielderror標籤的模板檔案或使用CSS樣式等方式去掉多餘的圓點
6.非欄位驗證
①欄位驗證:僅僅針對一個欄位進行的驗證,例如:針對一個age欄位進行驗證。
②非欄位驗證:驗證規則要檢查的資料不侷限於某一個欄位,而是根據多個欄位的值綜合進行驗證。例如:註冊使用者時,重複兩次填寫密碼,要求兩次密碼必須一致。
③錯誤訊息被儲存到了actionErrors屬性中,表示這個錯誤是“請求”級別的,不是某個欄位級別的。使用s:actionerror標籤顯示
7.短路驗證
①條件表示式:age > 50 && age < 100
②針對某一個欄位同時使用兩個驗證規則,預設情況下兩個驗證規則都會生效。如果希望第一規則驗證失敗,就不進行第二個規則的驗證,則可以將第一個規則短路。
③配置方式
8.與型別轉換協同工作
①提出問題:針對一個欄位進行驗證時,如果發生了型別轉換錯誤,那麼就沒必要再進行宣告式驗證了。
②涉及到的三個攔截器
[1]params攔截器:負責請求引數型別轉換
[2]conversionError攔截器:負責處理型別轉換過程中出現的錯誤
[3]validation攔截器:負責進行“宣告式驗證”
③實現方式:修改conversionError攔截器的原始碼
[1]明確要修改原始碼的類是:com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor
[2]建立包:com.opensymphony.xwork2.interceptor
[3]在com.opensymphony.xwork2.interceptor包下建立ConversionErrorInterceptor類
[4]從原版的類中,複製程式碼到山寨版的類中
[5]根據需要修改即可:在intercept()方法的return語句之前加入如下程式碼
④啟示:Struts2的任何一個攔截器在執行過程中都有兩個選擇
[1]繼續呼叫後續的攔截器或目標Action方法
[2]直接返回一個字串,以執行某個已經定義好的result
9.驗證訊息重用
①年齡和等級的錯誤訊息
②歸結為整數型別的通用的錯誤訊息
問題:訊息寫死之後分不清是哪個文字框提交的資料了
③在通用錯誤訊息中獲取欄位名稱
問題:為什麼${fieldName}能夠獲取到欄位名稱?
[1]${}裡面的字串是一個OGNL表示式
[2]OGNL表示式沒有以#開始,說明訪問的是物件棧,同時前面沒有使用[index],說明是從棧頂開始查詢屬性值
[3]驗證器物件在解析錯誤訊息時,會臨時把驗證器物件自己壓入棧頂,而驗證器物件就具有getFieldName()方法
④欄位名稱本身也希望能夠國際化
問題:getText(fieldName)是如何執行的?
[1]解析fieldName得到"age"或"grade"字串
[2]將"age"或"grade"字串傳遞給DefaultTextProvider物件的getText()方法
[3]getText()方法會到國際化資原始檔中查詢對應的值
10.自定義驗證器
①需求:驗證身份證號
②建立自定義驗證器類:擴充套件Struts2提供的介面或實現類
FieldValidatorSupport
需要實現validate()方法
③註冊
[1]註冊的目的:將自定義驗證規則和自定義驗證器類關聯起來
[2]在src目錄下建立validators.xml檔案,加入如下內容
11.同一個欄位在不同的action請求中使用不同驗證規則
①例子:UserAction中,對於userName欄位
登入:要求字串長度在5~10之間
註冊:要求字串長度在15~20之間
②配置檔案的格式:<ActionClassName>-<ActionAliasName>-validation.xml
③舉例:
登入:UserAction-login-validation.xml
註冊:UserAction-register-validation.xml
12.練習:在增刪改查操作中,針對新增和編輯圖書進行驗證
①書名:必須填
②作者:必須填
③價格:必須填
注意:字串要使用requiredstring規則驗證,因為如果字串沒有填,設定請求引數後,接收到的是空字串:"",和null是不一樣的,required只能檢測null,不能檢查空字串。
儘量使用包裝型別代替基本資料型別進行有沒有填寫驗證
requiredstring規則驗證可以進行自動去前後空格
<!-- 針對age欄位進行驗證 -->
<field
name=
"age">
<!-- 使用int驗證規則
-->
<field-validator
type="int">
<!-- 設定有效範圍的最小值為20 -->
<param
name=
"min">20</param
>
<!-- 設定有效範圍的最大值為50 -->
<param
name=
"max">50</param
>
<!-- 錯誤訊息,在錯誤訊息中可以使用OGNL表示式動態獲取驗證器物件的屬性值 --> |
<
validator
name
="int"
class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator" |
< |
<field name= "email"> <!-- 驗證字串長度 --> <field-validator type="stringlength" short-circuit="true" > <param name= "minLength">5</param > <param name= "maxLength">10</param > <param name= "trim">true</param > <message> Email長度要求在${minLength}和${maxLength}之間 </message> </field-validator > <!-- 驗證Email格式 --> <field-validator type="email"> <message> Email格式不正確</message > </field-validator > </field> |
//目標:如果發生了型別轉換錯誤,則返回"input",執行name=input的result,不執行後續的其他攔截器 //當然也不執行目標Action類的目標方法了 //1.獲取目標Action物件 Object action = invocation.getAction(); //2.檢測目標Action是否實現了ValidationAware介面 if(action instanceof ValidationAware) { //3.如果實現了ValidationAware介面,則轉換型別 ValidationAware va = (ValidationAware) action; //4.檢測是否包含錯誤資訊 if(va.hasErrors()) { //5.如果包含了錯誤資訊,則return "input"; return "input"; } } |
return invocation.invoke() |
return "指定result的name值"; |
Age must between ${ min} and ${max} |
Grade must between ${ min} and ${max} |
atguigu.int.msg=Integer value must between ${min} and ${max} |
atguigu.int.msg=${fieldName} must between ${min} and ${max} |
atguigu.int.msg=${getText(fieldName)} must between ${min } and ${max} age=AGE~ grade=GRADE~ |
/** * The validation implementation must guarantee that setValidatorContext will * be called with a non -null ValidatorContext before validate is called. * * @param object the object to be validated. 是執行驗證的目標Action類的物件 * @throws ValidationException is thrown if there is validation error(s). */ void validate (Object object ) throws ValidationException; |
<?xml version= "1.0" encoding ="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator Definition 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd" > <!-- START SNIPPET: validators-default --> <validators> <!-- name屬性:宣告驗證規則名稱,用於在驗證規則配置檔案中引用 --> <!-- class屬性:自定義驗證器類的全類名 --> <validator name= "idCard" class= "com.atguigu.validation.validator.IdCardValidator" /> </validators> |