1. 程式人生 > >struts2請求引數處理

struts2請求引數處理

今天總結一下struts2中有關action處理請求引數的兩部分核心內容,第一:請求引數的封裝,第二:請求引數的校驗。

Action處理請求引數

struts2 和 MVC 定義關係

StrutsPrepareAndExecuteFilter: 控制器

JSP : 檢視

Action : 可以作為模型,也可以是控制器

struts2 Action 接受請求引數 :屬性驅動 和 模型驅動

Action處理請求引數三種方式

第一種:Action 本身作為model物件,通過成員setter封裝 (屬性驅動 )

       頁面:

              使用者名稱 <input type="text" name="username" /><br/>

       Action:

              publicclass RegistAction1 extends ActionSupport {

                     privateString username;

                     publicvoid setUsername(String username) {

                            this.username= username;

                     }

              }

問題一: Action封裝資料,會不會有執行緒問題 ?

  *struts2 Action 是多例項 ,為了在Action封裝資料  (struts1 Action 是單例的 )

問題二: 在使用第一種資料封裝方式,資料封裝到Action屬性中,不可能將Action物件傳遞給 業務層

  * 需要再定義單獨JavaBean ,將Action屬性封裝到 JavaBean

第二種:建立獨立model物件,頁面通過ognl表示式封裝 (屬性驅動)

       頁面:

              使用者名稱 <input type="text" name="user.username" /><br/>  ----- 基於OGNL表示式的寫法

       Action:

              publicclass RegistAction2 extends ActionSupport {

                     private User user;

                     publicvoid setUser(User user) {

                            this.user= user;

                     }

                     publicUser getUser() {

                            returnuser;

                     }

              }

問題: 誰來完成的引數封裝

       <interceptor

name="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

第三種 :使用ModelDriven介面,對請求資料進行封裝 (模型驅動 ) ----- 主流

       頁面:

              使用者名稱 <input type="text" name="username" /><br/> 

       Action:

              publicclass RegistAction3 extends ActionSupport implements ModelDriven<User> {

                     privateUser user = new User(); // 必須手動例項化

                     publicUser getModel() {

                            returnuser;

                     }

              }

* struts2 有很多圍繞模型驅動的特性

* <interceptorname="modelDriven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>為模型驅動提供了更多特性

對比第二種、第三種 : 第三種只能在Action中指定一個model物件,第二種可以在Action中定義多個model物件

       <inputtype="text" name="user.username" />

       <inputtype="text" name="product.info" />

封裝資料到Collection和Map

1封裝資料到Collection物件

       頁面:

              產品名稱 <input type="text"name="products[0].name" /><br/>

       Action:

              publicclass ProductAction extends ActionSupport {

                     privateList<Product> products;

                     publicList<Product> getProducts() {

                            returnproducts;

                     }

                     publicvoid setProducts(List<Product> products) {

                            this.products= products;

                     }

              }

2封裝資料到Map物件

       頁面:

              產品名稱

<inputtype="text" name="map['one'].name" />

<br/> =======  one是map的鍵值

       Action:

              publicclass ProductAction2 extends ActionSupport {

                     private Map<String,Product> map;

                     publicMap<String, Product> getMap() {

                            returnmap;

                     }

                     publicvoid setMap(Map<String, Product> map) {

                            this.map= map;

                     }

              }    

Struts2型別轉換(瞭解)

1、 struts2 內部提供大量型別轉換器,用來完成資料型別轉換問題

boolean 和 Boolean

char和 Character

int 和 Integer

long 和 Long

float 和 Float

double 和 Double

Date 可以接收 yyyy-MM-dd格式字串

陣列  可以將多個同名引數,轉換到陣列中

集合  支援將資料儲存到 List 或者 Map 集合

案例: 輸入合法年齡和生日可以自動轉換

當輸入abc 轉換為 int型別 age時

              Causedby:    java.lang.NoSuchMethodException:

cn.xxxx.struts2.demo3.CustomerAction.setAge([Ljava.lang.String;

       分析: 輸入20 ,轉換 int型別20 --- setAge(int)

             輸入abc,轉換int 出錯 ---- setAge(String) ----- 報錯方法不存在異常

Jsp中接受異常資訊

<%@ taglib uri="/struts-tags"prefix="s"%>

<s:fielderror/>

請求引數校驗

校驗的分類 :客戶端資料校驗 和 伺服器端資料校驗

客戶端資料校驗 ,通過JavaScript 完成校驗 (改善使用者體驗,使使用者減少出錯 )

伺服器資料校驗 ,使用框架內建校驗功能(struts2 內建校驗功能 ) ----- 必須的

struts2 支援校驗方式

程式碼校驗 :在伺服器端通過編寫java程式碼,完成資料校驗

配置校驗 :XML配置校驗(主流) 和 註解配置校驗

手工程式碼校驗請求引數

步驟一: 封裝資料

       步驟二: 實現校驗Action ,必須繼承ActionSupport 類

       步驟三: 覆蓋validate方法,完成對Action的業務方法資料校

              通過程式碼邏輯判斷引數是否有效,如果引數非法 , this.addFieldError (ActionSupport提供)

              workflow攔截器 跳轉回 input頁面

       步驟四: 在jsp中 通過 <s:fieldError/> 顯示錯誤資訊

* validate方法會對Action中所有業務方法進行校驗,如果只想校驗某一個方法 validate方法名()

比如執行action裡面的名稱是add的方法,只想對add方法進行校驗

 validateAdd()

Xml配置方式資料校驗

XML配置方式資料校驗 (企業主流校驗)

       程式碼校驗 不適用於 大型專案, 流程資料複雜時,開發量和維護量都會很大

xml配置校驗原理: 將很多校驗規則程式碼已經寫好,只需要在xml中定義資料所使用校驗規則就可以了

       步驟一 :編寫jsp

       步驟二 :編寫Action 繼承ActionSupport 或者 實現 Validateable 介面

       步驟三 :封裝請求引數

                     *使用xml校驗 必須提供get方法

       步驟四 :編寫校驗規則xml檔案

              Action所在包編寫 Action類名-validation.xmlAction所有業務方法進行校驗

       引入DTD

              ------xwork-core-2.3.7.jar 中 xwork-validator-1.0.3.dtd

              <!DOCTYPEvalidators PUBLIC

             "-//Apache Struts//XWorkValidator 1.0.3//EN"

             "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">

       內建校驗器定義檔案

              xwork-core-2.3.7.jar中/com/opensymphony/xwork2/validator/validators/default.xml

<validators>

<!-- name:要校驗的欄位名 -->

<fieldname="username">

     <field-validatortype="requiredstring">

         <message>使用者名稱不能為空!(XML)</message>

     </field-validator>

</field>

內建校驗器

* required (必填校驗器,要求被校驗的屬性值不能為null)

* requiredstring (必填字串校驗器,要求被校驗的屬性值不能為null,並且長度大於0,預設情況下會對字串去前後空格)

* stringlength (字串長度校驗器,要求被校驗的屬性值必須在指定的範圍內,否則校驗失敗,minLength引數指定最小長度,maxLength引數指定最大長度,trim引數指定校驗field之前是否去除字串前後的空格)

* regex (正則表示式校驗器,檢查被校驗的屬性值是否匹配一個正則表示式,expression引數指定正則表示式,caseSensitive引數指定進行正則表示式匹配時,是否區分大小寫,預設值為true)

* int(整數校驗器,要求field的整數值必須在指定範圍內,min指定最小值,max指定最大值)

* double(雙精度浮點數校驗器,要求field的雙精度浮點數必須在指定範圍內,min指定最小值,max指定最大值)

* fieldexpression (欄位OGNL表示式校驗器,要求field滿足一個ognl表示式,expression引數指定ognl表示式,該邏輯表示式基於ValueStack進行求值,返回true時校驗通過,否則不通過)

* email(郵件地址校驗器,要求如果被校驗的屬性值非空,則必須是合法的郵件地址)

* url(網址校驗器,要求如果被校驗的屬性值非空,則必須是合法的url地址)

* date(日期校驗器,要求field的日期值必須在指定範圍內,min指定最小值,max指定最大值)

案例

required 必填校驗器

<field-validatortype="required">

      <message>性別不能為空!</message>

</field-validator>

requiredstring  必填字串校驗器

<field-validatortype="requiredstring">

      <param name="trim">true</param>

      <message>使用者名稱不能為空!</message>

</field-validator>

stringlength:字串長度校驗器

<field-validatortype="stringlength">

       <paramname="maxLength">10</param>

       <paramname="minLength">2</param>

       <paramname="trim">true</param>

       <message><![CDATA[產品名稱應在2-10個字元之間]]></message>

</field-validator>

int:整數校驗器

<field-validatortype="int">

       <paramname="min">1</param>

       <paramname="max">150</param>

       <message>年齡必須在1-150之間</message>

</field-validator>

date: 日期校驗器

<field-validatortype="date">

       <paramname="min">1900-01-01</param>

       <paramname="max">2050-02-21</param>

       <message>生日必須在${min}到${max}之間</message>

</field-validator>

url: 網路路徑校驗器

<field-validatortype="url">

       <message>xxxx播客的主頁地址必須是一個有效網址</message>

</field-validator>

email:郵件地址校驗器

<field-validatortype="email">

       <message>電子郵件地址無效</message>

</field-validator>

regex:正則表示式校驗器

<field-validator type="regex">

     <paramname="expression"><![CDATA[^13\d{9}$]]></param>

     <message>手機號格式不正確!</message>

</field-validator>

fieldexpression : 欄位表示式校驗

<field-validatortype="fieldexpression">

      <param name="expression"><![CDATA[(password==repassword)]]></param>

      <message>兩次密碼輸入不一致</message>

</field-validator>

=============================

如何對指定的方法校驗

格式 Action類名-ActionName(<action>元素name屬性)-validation.xml

       例如 : 校驗AddCustomerAction中execute方法 配置 <action

name="addcustomer".../> 校驗檔名字:

 AddCusotmerAction-addcustomer-validation.xml

自定義校驗規則(瞭解)

步驟一: 自定義校驗器必須實現 Validator  介面

              通常自定義校驗器 繼承 ValidatorSupport 和 FieldValidatorSupport 

              *ValidatorSupport 針對不是一個輸入欄位 (兩個密碼一致)

              *FieldValidatorSupport 針對是一個輸入欄位  (使用者名稱非空)

       步驟二: 註冊校驗器

              在工程的src下新建validators.xml檔案

              引入 xwork-core-2.3.7.jar中xwork-validator-config-1.0.dtd 

       步驟三 :使用校驗器

              在Action所在包 建立Action類名-validation.xml

編寫一個類繼承FieldValidatorSupport :

public class MyAgeValidator extends FieldValidatorSupport {

public void validate(Objectobj) throws ValidationException {

     // 獲得欄位名稱:

     String name =this.getFieldName();

     // 獲得欄位的值:

     Object value =  this.getFieldValue(name, obj);

     if(value instanceofInteger){

         int age = (Integer)value;

         if(age < 0){

             this.addFieldError(name,obj);

         }

     }

}

}

*註冊校驗規則:

* 在src下建立一個validators.xml

* 引入一個DTD:

* xwork-core-2.3.7.jar下的xwork-validator-config-1.0.dtd

* 配置:

<!DOCTYPE validators PUBLIC "-//Apache Struts//XWorkValidator Config 1.0//EN"

 "http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd">

<validators>

<validator name="aaa" class="cn.xxxx.action.demo6.MyAgeValidator"></validator>

</validators>

* 使用校驗規則:

<validators>

<fieldname="age">

     <field-validatortype="aaa">

         <message>年齡不能為負數!</message>

     </field-validator>

</field>

</validators>

**** 實際開發中很少用到自定義校驗器