目錄
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
-
封裝數(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)換。
步驟:
- 創(chuàng)建一個類實現(xiàn)TypeConverter接口.
- 重寫接口中方法,實現(xiàn)類型轉(zhuǎn)換操作.
- 注冊類型轉(zhuǎn)換器.
** 創(chuàng)建自定義類型轉(zhuǎn)換器的方法 **
- 實現(xiàn)TypeConverter,重寫方法
public Object convertValue(Map<String, Object> context, Object target,
Member member, String propertyName, Object value, Class toType); - 繼承 DefaultTypeConverter類
public Object convertValue(Map<String, Object> context, Object value, Class toType) {
return convertValue(value, toType);
} - 繼承DefaultTypeConverter類的一個子類StrutsTypeConverter(推薦)
public abstract Object convertFromString(Map context, String[] values, Class toClass);
public abstract String convertToString(Map context, Object o);
** 注冊一個自定義類型轉(zhuǎn)換器 **
- 局部--針對于action
配置文件所在位置以及名稱: 在Action類所在包 創(chuàng)建 Action類名-conversion.properties ,
配置文件書寫: 格式 : 屬性名稱=類型轉(zhuǎn)換器的全類名 - 局部--針對于model
配置文件所在位置以及名稱: 在model類所在包 創(chuàng)建 model類名-conversion.properties ,
配置文件書寫: 格式 : 屬性名稱=類型轉(zhuǎn)換器的全類名 -
全局
配置文件所在位置以及名稱:在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