Struts2干貨筆記——第二天

目錄

1. Struts2提供了三種數(shù)據(jù)封裝的方式
2. 封裝數(shù)據(jù)到Collection和Map
3. Struts2類型轉(zhuǎn)換器
4. 類型轉(zhuǎn)換器中的錯誤處理
5. 請求參數(shù)驗證
6. 對action中的指定方法進(jìn)行校驗
Struts2提供了三種數(shù)據(jù)封裝的方式
1. 屬性驅(qū)動
  • Action本身作為model對象,通過setter封裝
    頁面:
    用戶名 <input type="text" name="username" />

    Action :
    public class RegistAction extends ActionSupport {
    private String username;
    public void setUsername(String username) {
    this.username = username;
    }
    }

  • 創(chuàng)建獨立的model對象,頁面通過ognl表達(dá)式封裝
    頁面:
    用戶名 <input type="text" name="user.username" />
    // 基于OGNL表達(dá)式的寫法
    Action:
    public class RegistAction2 extends ActionSupport {
    private User user;
    public void setUser(User user) {
    this.user = user;
    }

       public User getUser() {
           return user;
       }
     }
    
2. 模型驅(qū)動(主流)
  • 使用ModelDriven接口,對請求參數(shù)進(jìn)行封裝
    頁面:
    用戶名 <input type="text" name="username" />

    Action :
    public class RegistAction3 extends ActionSupport implements ModelDriven<User> {
    private User user = new User(); // 必須手動實例化
    public User getModel() {
    return user;
    }
    }

封裝數(shù)據(jù)到Collection和Map

  1. 封裝數(shù)據(jù)到Collection,常見于需要快速錄入批量數(shù)據(jù)的場景
    頁面:
    產(chǎn)品名稱 <input type="text" name="products[0].name" />

    Action :
    public class ProductAction extends ActionSupport {
    private List<Product> products;

         public List<Product> getProducts() {
             return products;
         }
    
         public void setProducts(List<Product> products) {
             this.products = products;
         }
     }
    

頁面:
產(chǎn)品名稱 <input type="text" name="map['one'].name" />
-- one是map的鍵值
Action :
public class ProductAction2 extends ActionSupport {
private Map<String, Product> map;

        public Map<String, Product> getMap() {
            return map;
        }

        public void setMap(Map<String, Product> map) {
            this.map = map;
        }
    }   

Struts2類型轉(zhuǎn)換器

當(dāng)我們發(fā)送一個HTTP請求時,請求的內(nèi)容都以字符串的形式發(fā)送給服務(wù)器,所以需要轉(zhuǎn)換成Action里定義的類型,例如,如果你的Action類中有一個integer屬性,你不需要執(zhí)行任何操作,Struts會自動將請求參數(shù)轉(zhuǎn)換為integer屬性。對于大部分常用類型,無需創(chuàng)建轉(zhuǎn)換器,Struts2內(nèi)置了很多常見數(shù)據(jù)類型的轉(zhuǎn)換器。

  • boolean 和 Boolean
  • char和 Character
  • int 和 Integer
  • long 和 Long
  • float 和 Float
  • double 和 Double
  • Date 可以接收 yyyy-MM-dd格式字符串
  • 數(shù)組 可以將多個同名參數(shù),轉(zhuǎn)換到數(shù)組中
  • 集合 支持將數(shù)據(jù)保存到 List 或者 Map 集合

struts2中的類型轉(zhuǎn)換器根接口是:com.opensymphony.xwork2.conversion.TypeConverter。

自定義類型轉(zhuǎn)換器

Date類型的屬性可以接收格式為2000-02-20的請求參數(shù),但是如果要接收格式為20000220的請求參數(shù),就必須要自定義類型轉(zhuǎn)換器,否則struts2無法自動完成類型轉(zhuǎn)換。

步驟:

  1. 創(chuàng)建一個類實現(xiàn)TypeConverter接口.
  2. 重寫接口中方法,實現(xiàn)類型轉(zhuǎn)換操作.
  3. 注冊類型轉(zhuǎn)換器.

** 創(chuàng)建自定義類型轉(zhuǎn)換器的方法 **

  1. 實現(xiàn)TypeConverter,重寫方法
    public Object convertValue(Map<String, Object> context, Object target,
    Member member, String propertyName, Object value, Class toType);
  2. 繼承 DefaultTypeConverter類
    public Object convertValue(Map<String, Object> context, Object value, Class toType) {
    return convertValue(value, toType);
    }
  3. 繼承DefaultTypeConverter類的一個子類StrutsTypeConverter(推薦)
    public abstract Object convertFromString(Map context, String[] values, Class toClass);
    public abstract String convertToString(Map context, Object o);

** 注冊一個自定義類型轉(zhuǎn)換器 **

  1. 局部--針對于action
    配置文件所在位置以及名稱: 在Action類所在包 創(chuàng)建 Action類名-conversion.properties ,
    配置文件書寫: 格式 : 屬性名稱=類型轉(zhuǎn)換器的全類名
  2. 局部--針對于model
    配置文件所在位置以及名稱: 在model類所在包 創(chuàng)建 model類名-conversion.properties ,
    配置文件書寫: 格式 : 屬性名稱=類型轉(zhuǎn)換器的全類名
  3. 全局
    配置文件所在位置以及名稱:在src下創(chuàng)建一個xwork-conversion.properties
    配置文件書寫: 格式: 要轉(zhuǎn)換的類型全名=類型轉(zhuǎn)換器的全類名


    舉例.PNG

類型轉(zhuǎn)換器中的錯誤處理

我們希望用戶輸入abc,def模式的字符串,輸入的字符串包含一個英文逗號作為用戶名和密碼的分隔符,如果用戶輸入了多個英文逗號,或者沒有輸入英文逗號,都將引起系統(tǒng)異常,因為上面的類型轉(zhuǎn)換器將無法正常解出用戶名和密碼,實際上,表現(xiàn)層數(shù)據(jù)涉及兩個處理:數(shù)據(jù)校驗和類型轉(zhuǎn)換是緊密相關(guān)的,只有當(dāng)輸入數(shù)據(jù)時有效數(shù)據(jù)時,系統(tǒng)才可以進(jìn)行有效的類型轉(zhuǎn)換——當(dāng)然,有時候即使用戶輸入的數(shù)據(jù)能進(jìn)行有效轉(zhuǎn)換,但依然是非法數(shù)據(jù)(假設(shè)需要輸入一個人的年齡,輸入200則是非法數(shù)據(jù))。因此,可以進(jìn)行有效的類型轉(zhuǎn)換時基礎(chǔ),只有當(dāng)數(shù)據(jù)完成了有效的類型轉(zhuǎn)換后,下一步才去做數(shù)據(jù)校驗。

Struts2提供了一個名為conversion-Error的攔截器,這個攔截器被注冊在默認(rèn)的攔截器棧中,我們查看Struts2框架的默認(rèn)配置文件:struts-default.xml文件,
<interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>

通過分析攔截器作用,得知當(dāng)類型轉(zhuǎn)換出錯時,自動跳轉(zhuǎn)input視圖 ,在input視圖頁面中 <s:fieldError/> 顯示錯誤信息
在Action所在包中,創(chuàng)建 ActionName.properties,在局部資源文件中配置提示信息 : invalid.fieldvalue.屬性名= 錯誤信息

請求參數(shù)驗證

兩種方式:

  • 手動校驗
  • 配置校驗(xml)

** 1. 手動校驗(了解) **

  • 繼承ActionSupport,重寫validate()方法,在該方法中完成驗證,validate()方法在其他的業(yè)務(wù)方法之前執(zhí)行
  • 驗證出錯后轉(zhuǎn)向的頁面
    struts.xml配置<result name="input">/validate/login.jsp</result>
  • 什么時候表示驗證出錯?
    this.addFieldError("a","錯誤信息");方法指向的一個集合
    當(dāng)集合不為空時,轉(zhuǎn)向錯誤頁面。
    在jsp頁面中使用
    <s:fielderror> 展示所有錯誤信息
    <s:fielderror fieldName="">展示特定名稱的錯誤信息

** 2. 配置校驗(重點) **
要求:action類必須繼承自ActionSupport
配置文件:

  • 位置:xml文件要與action類在同一個包下
  • 名稱:action類名-validation.xml
  • 約束: xwork-core-2.3.7.jar 中 xwork-validator-1.0.3.dtd 下
    <!DOCTYPE validators PUBLIC
    "-//Apache Struts//XWork Validator 1.0.3//EN"
    "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
  • 寫法:
    1)根元素<validators>
    2)子元素<field name="屬性名稱"></field>,name為頁面被驗證的表單字段的名稱
    3)<field>的子元素<field-validator type="校驗器"> 這個是指定校驗器
    校驗器有哪些?
    在xwork-core-2.3.7.jar 中 /com/opensymphony/xwork2/validator/validators/default.xml下
    <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
    <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
    <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
    <validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
    <validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
    <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
    <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
    <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
    <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
    <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
    <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
    <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
    <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
    <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
    <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
    <validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
    4)<field-validator>的子元素<message>錯誤信息</message>
    5)<field-validator>子元素的<param name="">值</param>用于指定校驗器中的參數(shù)

** 系統(tǒng)提供的校驗器:**

  • required (必填校驗器,要求被校驗的屬性值不能為null)
  • requiredstring (必填字符串校驗器,要求被校驗的屬性值不能為null,并且長度大于0,默* 認(rèn)情況下會對字符串去前后空格)
  • stringlength (字符串長度校驗器,要求被校驗的屬性值必須在指定的范圍內(nèi),否則校驗失敗,minLength參數(shù)指定最小長度,maxLength參數(shù)指定最大長度,trim參數(shù)指定校驗
  • field之前是否去除字符串前后的空格)
  • regex (正則表達(dá)式校驗器,檢查被校驗的屬性值是否匹配一個正則表達(dá)式,expression參數(shù)指定正則表達(dá)式,caseSensitive參數(shù)指定進(jìn)行正則表達(dá)式匹配時,是否區(qū)分大小寫,默認(rèn)值為true)
  • int(整數(shù)校驗器,要求field的整數(shù)值必須在指定范圍內(nèi),min指定最小值,max指定最大值)
  • double(雙精度浮點數(shù)校驗器,要求field的雙精度浮點數(shù)必須在指定范圍內(nèi),min指定最小值,max指定最大值)
  • fieldexpression (字段OGNL表達(dá)式校驗器,要求field滿足一個ognl表達(dá)式,expression參數(shù)指定ognl表達(dá)式,該邏輯表達(dá)式基于ValueStack進(jìn)行求值,返回true時校驗通過,否則不通過)
  • email(郵件地址校驗器,要求如果被校驗的屬性值非空,則必須是合法的郵件地址)
  • url(網(wǎng)址校驗器,要求如果被校驗的屬性值非空,則必須是合法的url地址)
  • date(日期校驗器,要求field的日期值必須在指定范圍內(nèi),min指定最小值,max指定最大值)

required 必填校驗器

<field-validator type="required">
<message>性別不能為空!</message>
</field-validator>
```

requiredstring  必填字符串校驗器
```
<field-validator type="requiredstring">
       <param name="trim">true</param>
       <message>用戶名不能為空!</message>
</field-validator>
```
stringlength:字符串長度校驗器
```
<field-validator type="stringlength">
    <param name="maxLength">10</param>
    <param name="minLength">2</param>
    <param name="trim">true</param>
    <message><![CDATA[產(chǎn)品名稱應(yīng)在2-10個字符之間]]></message>
</field-validator>
```
int:整數(shù)校驗器
```
<field-validator type="int">
    <param name="min">1</param>
    <param name="max">150</param>
    <message>年齡必須在1-150之間</message>
</field-validator>
```
date: 日期校驗器
```
<field-validator type="date">
    <param name="min">1900-01-01</param>
    <param name="max">2050-02-21</param>
    <message>生日必須在${min}到${max}之間</message>
</field-validator>

url:  網(wǎng)絡(luò)路徑校驗器
<field-validator type="url">
    <message>傳智播客的主頁地址必須是一個有效網(wǎng)址</message>
</field-validator>
```
email:郵件地址校驗器
```
<field-validator type="email">
    <message>電子郵件地址無效</message>
</field-validator>
```
regex:正則表達(dá)式校驗器
```
<field-validator type="regex">
     <param name="regexExpression"><![CDATA[^13\d{9}$]]></param>
     <message>手機號格式不正確!</message>
</field-validator>
```
fieldexpression : 字段表達(dá)式校驗
```
<field-validator type="fieldexpression">
       <param name="expression"><![CDATA[(password==repassword)]]></param>
       <message>兩次密碼輸入不一致</message>
</field-validator>
```

**對action中的指定方法進(jìn)行校驗**
當(dāng)校驗文件的取名為ActionClassName-validation.xml時,會對action中的所有處理方法實施輸入驗證,如果只需要對action中的某個action方法校驗,那么,校驗文件的取名應(yīng)該為ActionClassName-ActionName-validation.xml,**其中ActionName為Struts.xml中action的名稱**。例如:
```
<action name="user_*" class="com.java.action.UserAction" method="{1}" >
        <result name="success">/WEB-INF/page/message.jsp</result>
        <result name="input">/WEB-INF/page/addUser.jsp</result>
</action>
```
在UserAction中有兩個處理方法:
public String add() throws Exception{}
public String update() throws Exception{}
要對add()方法實施驗證,校驗文件取名為:UserAction-user_add-validation.xml
要對update()方法實施驗證,校驗文件取名為:UserAction-user_update-validation.xml
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評論 6 538
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,067評論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,184評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,582評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,794評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,343評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,096評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,291評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,513評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,026評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,253評論 2 375

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,729評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,808評論 18 139
  • 概述 Struts就是基于mvc模式的框架!(struts其實也是servlet封裝,提高開發(fā)效率!) Strut...
    奮斗的老王閱讀 2,967評論 0 51
  • 果然,只有閑的人才會想太多。 不,應(yīng)該是閑的時候會為浪費時間而焦急,難過,自責(zé)。所以,多種負(fù)面的情緒積雜在一起,整...
    AliveorDead閱讀 203評論 0 0
  • 選擇拍攝室內(nèi)婚紗照有什么技巧 遂寧婚紗攝影價格最低多少錢? 選擇拍攝室內(nèi)韓式婚紗照有什么技巧 拍室內(nèi)婚紗照,一樣拍...
    遂寧金公主攝影客服閱讀 489評論 0 0