![](https://github.com/gefenghua/MarkdownPictures/raw/master/struts_icon.jpg)
一惭载、概述
Struts是Apache基于Model2模型(MVC設(shè)計(jì)模式)開發(fā)的一個(gè)開源的Web應(yīng)用框架泳猬,由一組相互協(xié)作的類或組件制轰、Servlet以及jsp標(biāo)簽庫(kù)組成灯谣。
Struts采用攔截器的機(jī)制來(lái)處理用戶的請(qǐng)求,也使得業(yè)務(wù)邏輯控制器能夠與Servlet完全脫離曲掰,大大縮減了使用MVC模式開發(fā)web應(yīng)用的時(shí)間疾捍,降低了程序的復(fù)雜度,提高了開發(fā)效率栏妖。
Struts具有如下一些特點(diǎn):
- 提供了攔截器乱豆,利用攔截器可以進(jìn)行AOP(面向方面)編程,實(shí)現(xiàn)如權(quán)限攔截等功能
- 提供了類型轉(zhuǎn)換器吊趾,可以把特殊的請(qǐng)求參數(shù)轉(zhuǎn)化成需要的類型
- 提供支持多種表現(xiàn)層技術(shù)宛裕,如:JSP、FreeMarker等
- 輸入校驗(yàn)可以對(duì)指定的方法進(jìn)行校驗(yàn)
- 提供了全局范圍论泛、包范圍和Action范圍的國(guó)際化資源文件管理實(shí)現(xiàn)
二揩尸、原理
1、核心控制器FilterDispatcher
FilterDispatcher是Struts框架的核心和基礎(chǔ)屁奏,包含了框架內(nèi)部的控制流程和處理機(jī)制岩榆。該控制器作為一個(gè)Filter運(yùn)行在Web應(yīng)用中,負(fù)責(zé)攔截web.xml文件中<url-pattern>指定的用戶請(qǐng)求坟瓢。如果請(qǐng)求以action結(jié)尾勇边,該請(qǐng)求將被轉(zhuǎn)入Struts框架處理,否則將略過(guò)該請(qǐng)求折联。Struts框架獲得請(qǐng)求后粥诫,將根據(jù)請(qǐng)求的前面部分決定調(diào)用哪個(gè)業(yè)務(wù)邏輯組件。
2崭庸、業(yè)務(wù)控制器Action
Struts應(yīng)用中的Action都被定義在struts.xml文件中,在該文件中定義了Action的name屬性和class屬性。其中name屬性決定了該Action處理哪個(gè)請(qǐng)求怕享,class屬性決定了該Action的實(shí)現(xiàn)類执赡。Struts用于處理用戶請(qǐng)求的Action實(shí)例,并不是用戶所實(shí)現(xiàn)的業(yè)務(wù)控制器函筋,而是Action代理沙合。Struts框架提供了攔截器,負(fù)責(zé)將HttpServletRequest請(qǐng)求中的參數(shù)解析出來(lái)跌帐,傳入到Action中首懈,并回調(diào)Action的execute方法來(lái)處理用戶請(qǐng)求。
3谨敛、業(yè)務(wù)邏輯組件
用于實(shí)現(xiàn)具體的業(yè)務(wù)邏輯究履。
三、配置
- 從Struts官網(wǎng)下載相應(yīng)版本的壓縮文件脸狸,解壓縮
- 將需要的jar包拷貝到工程WEB-INF/lib目錄下
- 配置struts.xml文件最仑,添加Action的相關(guān)配置
- 配置web.xml文件,添加啟動(dòng)Struts的過(guò)濾器
四炊甲、工作流程
- 客戶端瀏覽器發(fā)送HTTP請(qǐng)求
- Servlet容器通過(guò)web.xml映射請(qǐng)求泥彤,獲得控制器的名字,并調(diào)用控制器FilterDispatcher(2.1版本以前)或StrutsPrepareAndExecuteFilter(2.1版本以后)
- 控制器通過(guò)ActionMapper獲得Action的信息卿啡,并調(diào)用ActionProxy
- ActionProxy通過(guò)ConfigurationManager讀取struts.xml文件獲取action和interceptor信息吟吝,并把請(qǐng)求傳遞給ActionInvocation
- ActionInvocation依次調(diào)用action和interceptor,根據(jù)action的配置信息颈娜,產(chǎn)生result
- 將Result信息返回給ActionInvocation
- 生成HttpServletResponse響應(yīng)剑逃,并將其發(fā)送給客戶端
五、攔截器
Struts2框架的絕大部分功能是通過(guò)攔截器來(lái)完成的揭鳞。當(dāng)FilterDispatcher攔截到用戶請(qǐng)求后炕贵,對(duì)用戶請(qǐng)求進(jìn)行處理,然后調(diào)用用戶自定義的Action類中的方法來(lái)處理請(qǐng)求野崇。
在struts.xml文件中称开,使用<interceptor>元素來(lái)進(jìn)行定義:
<interceptor name="攔截器名" class="攔截器實(shí)現(xiàn)的類">
<param name="參數(shù)名">參數(shù)值</param>
</interceptor>
有時(shí)一個(gè)Action要配置不止一個(gè)攔截器,這時(shí)就要配置多個(gè)攔截器組成的攔截器棧:
<interceptor-stack name="攔截器棧名">
<interceptor-ref name="攔截器一"></interceptor-ref>
<interceptor-ref name="攔截器二"></interceptor-ref>
<interceptor-ref name="攔截器三"></interceptor-ref>
</interceptor-stack>
Tips:每個(gè)包中只能有一個(gè)默認(rèn)的攔截器乓梨,一旦為包中的某個(gè)action指定了攔截器鳖轰,則默認(rèn)的攔截器將不起作用。
Struts提供了攔截器接口Interceptor扶镀,其中包含三個(gè)方法:
- init()蕴侣,初始化要使用的資源
- intercept(ActionInvocation invocation),實(shí)現(xiàn)攔截的動(dòng)作
- destroy()臭觉,銷毀在init方法中打開的資源
六昆雀、校驗(yàn)
可以通過(guò)兩種方式進(jìn)行校驗(yàn):實(shí)現(xiàn)validate方法和通過(guò)validation配置文件辱志。
1、實(shí)現(xiàn)validate方法
在Validateable接口中定義了一個(gè)validate()方法狞膘,在用戶自定義的Action類中重寫該方法就可以實(shí)現(xiàn)校驗(yàn)功能揩懒。當(dāng)數(shù)據(jù)校驗(yàn)發(fā)生錯(cuò)誤時(shí),調(diào)用addFieldError()方法向相同的fieldErrors添加校驗(yàn)錯(cuò)誤信息挽封。
public void validate() {//會(huì)對(duì)action中的所有方法進(jìn)行校驗(yàn)
if(this.username == null || this.username.trim().equals("")) {
this.addFieldError("username", "用戶名不能為空已球!");
}
if(this.mobile == null || this.mobile.trim().equals("")) {
this.addFieldError("mobile", "手機(jī)號(hào)不能為空!");
} else {
if(!Pattern.compile("^1[358]\\d{9}{1}quot;).matcher(this.mobile).matches()) {
this.addFieldError("mobile", "手機(jī)號(hào)格式不正確辅愿!");
}
}
}
如果系統(tǒng)的fieldErrors包含錯(cuò)誤信息智亮,Struts會(huì)將請(qǐng)求結(jié)果發(fā)送到名為input的result。在Action的配置中添加對(duì)input的響應(yīng)并指定要跳轉(zhuǎn)的頁(yè)面:
<action name="LoginAction" class="com.login.LoginAction">
<!-- 定義邏輯視圖和物理資源之間的映射 -->
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/main.jsp</result>
</action>
result的name屬性有如下幾種方式:
- success:表示請(qǐng)求處理成功点待,默認(rèn)值
- error:表示請(qǐng)求處理失敗
- none:表示請(qǐng)求處理完成后不跳轉(zhuǎn)
- input:表示輸入時(shí)如果驗(yàn)證失敗應(yīng)跳轉(zhuǎn)何處
- login:表示登錄失敗后跳轉(zhuǎn)何處
在input映射的頁(yè)面中通過(guò)<s:fielderror/>顯示錯(cuò)誤信息:
<s:fielderror></s:fielderror>
<form method="post" action="<%=basePath%>person/save.action">
用戶名:<input type="text" name="username"/>不能為空<br/>
手機(jī)號(hào):<input type="text" name="mobile"/>不能為空阔蛉,并且要符合手機(jī)號(hào)的格式<br/>
<input type="submit" value="提交"/>
</form>
2、通過(guò)validation配置
另一種方式是提供校驗(yàn)文件亦鳞,校驗(yàn)文件和action類在同一個(gè)包下馍忽,文件命名規(guī)則是ActionClassName-validation.xml。在校驗(yàn)文件中燕差,使用數(shù)據(jù)校驗(yàn)器來(lái)對(duì)表單進(jìn)行校驗(yàn)遭笋。
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用戶名不能為空!</message>
</field-validator>
</field>
<field name="mobile">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>手機(jī)號(hào)不能為空徒探!</message>
</field-validator>
<field-validator type="regex">
<param name="expression"><![CDATA[^1[358]\d{9}$]]></param>
<message>手機(jī)格式不正確瓦呼!</message>
</field-validator>
</field>
</validators>
Struts提供了大量的數(shù)據(jù)校驗(yàn)器,包括表單校驗(yàn)器和非表單校驗(yàn)器:
- 必填校驗(yàn)器测暗,類型為required
- 整數(shù)校驗(yàn)器央串,類型為int
- 日期校驗(yàn)器,類型為date
- 郵件地址校驗(yàn)器碗啄,類型為email
- 網(wǎng)址校驗(yàn)器质和,類型為url
- 必填字符串校驗(yàn)器,類型為requiredstring
- 字符串長(zhǎng)度校驗(yàn)器稚字,類型為stringlength
- 正則表達(dá)式校驗(yàn)器饲宿,類型為regex
七、標(biāo)簽
按照標(biāo)簽的功能大致可以分為兩類:UI標(biāo)簽和非UI標(biāo)簽胆描。要想使用Struts標(biāo)簽瘫想,需要在使用標(biāo)簽的jsp頁(yè)面引入標(biāo)簽庫(kù)。
<%@ taglib uri="/struts-tags" prefix="s" %>
1昌讲、UI標(biāo)簽
主要用于生成HTML元素吠架,可分為表單標(biāo)簽和非表單標(biāo)簽荧库。
表單標(biāo)簽在語(yǔ)法上與普通的HTML元素標(biāo)簽類似,在HTML元素前加上“s:”前綴即可。在用法上也基本與普通元素相同菠劝。通常情況下,會(huì)使用與UI有關(guān)的框架來(lái)代替這部分標(biāo)簽。
- <s:form>表單標(biāo)簽,通常會(huì)使用action屬性指定Action類
- <s:submit>饶碘、<s:reset>用來(lái)提交/重置表單
- <s:hidden>用來(lái)表示表單的隱藏域
非表單標(biāo)簽主要用于生成非表單的可視化元素,如:Tab頁(yè)馒吴、樹形結(jié)構(gòu)等,也可以用于自定義的組件瑟曲。還可以用來(lái)顯示Action的信息饮戳。
- <s:component>用來(lái)表示自定義組件
- <s:fielderror>用來(lái)輸出表單域的錯(cuò)誤信息
- <s:actionerror>用來(lái)輸出getActionErrors()方法返回的非空信息
- <s:actionmessage>用來(lái)輸出getActionMessage()方法返回的信息
2、非UI標(biāo)簽
主要用于邏輯控制洞拨、數(shù)據(jù)訪問(wèn)等扯罐,可分為控制標(biāo)簽和數(shù)據(jù)訪問(wèn)標(biāo)簽。
控制標(biāo)簽包括:
- <s:if>烦衣、<s:elseif>歹河、<s:else>用于控制選擇輸出
- <s:append>用于將多個(gè)集合拼成一個(gè)新的集合,按照集合的排列順序拼接
- <s:generator>用于將一個(gè)字符串解析成一個(gè)集合
- <s:iterator>用于將集合中的元素迭代輸出
- <s:merge>用于將多個(gè)集合拼成一個(gè)新的集合花吟,按照各集合中元素的順序拼接
- <s:sort>用于對(duì)集合進(jìn)行排序
- <s:subset>用于截取集合生成新的子集合
數(shù)據(jù)訪問(wèn)標(biāo)簽包括:
- <s:action>允許在jsp頁(yè)面中直接使用Action
- <s:bean>用來(lái)實(shí)例化一個(gè)JavaBean
- <s:date>用來(lái)格式化輸出日期
- <s:property>用來(lái)輸出對(duì)象的屬性值
- <s:url>用來(lái)創(chuàng)建一個(gè)URL地址
- <s:param>用來(lái)為其他標(biāo)簽提供參數(shù)