一、struts概述
1、Struts實現MVC設計模式
(1)Struts實質上就是在JSPModel2的基礎山實現一個MVC框架。
1)模型:由業務實現業務邏輯的JavaBean或EJB組件構成
2)控制器:由ActionServlet和Action來實現
3)視圖:由一組JSP文件構成
(2)Struts的結構:
2、Struts的工作流程
(1)Web應用啟動時加載並初始化ActionServlet,ActionServlet從struts-config.xml中讀取配置信息,把它們存放到各種配置對象中。
(2)當ActionServlet接收到一個客戶請求時,檢索和用戶請求匹配的ActionMapping實例,如果不存在,就返回用戶請求路徑無效的信息。
(3)如果ActionForm實例不存在,就創建一個ActionForm對象,把客戶提交的表單數據保存到ActionForm對象中。
(4)根據配置信息決定是否需要表單驗證。如果需要驗證,就調用ActionForm的validate()。
(5)ActionForm的validate()方法
①如果返回null或返回一個不包含ActionMessage的ActionErrors對象,就表示表單驗證成功。
②如果返回一個包含一個或多個ActionMessage的ActionErrors對象,就表示表單驗證失敗,此時ActionServlet將直接把請求轉發給包含用戶提交表單的JSP組件。在這種情況下,不會再創建Action對象並調用Action的execute()方法。
(6)ActionServlet根據ActionMapping實例包含的映射信息決定將請求轉發給哪個Action。如果相應的Action實例不存在,就先創建這個實例,然後調用Action的execute()方法。
(7)Action的execute()方法返回一個ActionForward對象,ActionServlet再把客戶請求轉發給ActionForward對象指向的JSP組件。
(8)ActionForward對象指向的JSP組件生成動態網頁,返回給客戶。
二、Struts 1.2 構成
1、struts運行需要的jar包
(1)commons-digester.jar
用於解析配置文件
(2)commons-fileupload.jar
用於實現文件上傳(進行了進一步的封裝)
(3)commons-logging.jar 用於日志處理
(4)commons-beanutils.jar 用於POJO的屬性賦值、拷貝等
(5)commons-validator.jar 用於表單驗證
2、 struts標記庫文件(tld)
(1)struts-bean.tld
(2)struts-html.tld
(3)struts-logic.tld
(4)struts-nested.tld
(5)struts-tiles.tld
3、配置文件struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans>
<form-bean name="xxx" type="ActionForm的類全名">
<form-bean name="LoginForm" type="basic.LoginForm">
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings >
<action path="action的路徑,在form的action中寫的那個路徑" type="Action的類全名" name="form的名字" scope="request|session(默認值)">
<forward name="在自定義的Action中使用的findForward方法的參數" path="跳轉頁面的路徑" redirect="false"(重定向,默認false)/>
</action>
</action-mappings>
<message-resources parameter="資源文件的名字(不加後綴)" />
</struts-config>
4、資源文件
<message-resources parameter="ApplicationResources" >
</message-resources>
使用資源文件的步驟:
(1)確認資源文件的jar導入
(2)引入標記庫 <%@tagliburi="/WEB-INF/struts-bean.tld" prefix="bean" %>
(3) 使用:
ApplicationResources.properties文件以“消息key、消息文本”格式存放數據
eg.
ApplicationResources.properties中:
jsp.user=username
test.jsp中:
<bean:message key="jsp.user"/>
注意:ApplicationResources.properties文件不支持中文,如果想在頁面中展示中文只能把中文轉為unicode碼,命令:native2ascii 原文件名 目標文件名。
國際化:按照浏覽器所要求的語言選擇資源文件。前面相同,後綴不同。
eg.
<message-resources parameter="ApplicationResources" >
</message-resources>
資源文件名為:ApplicationResources_zh.properties(中文)
ApplicationResources_en.properties(英文)
也可以加上國家名
ApplicationResources_zh_CN.properties(中文)
ApplicationResources_en_US.properties(英文)
注意:資源文件的選擇:首先查找和浏覽器語言匹配的資源文件,如果找不到則找和服務器的語言地區相匹配資源文件,如果還是找不到就查找默認不帶語言後綴的資源文件。
三、Struts1.2核心控制流程
1、主要組件:
(1)ActionServlet組件:充當Struts框架的中央控制器
(2)RequestProcessor組件:充當每個子應用模塊的請求處理器
(3)Action組件:負責處理一項具體的業務。
2、ActionServlet
(1)Struts的啟動通常從加載ActionServlet開始(如果沒有其他Servlet的加載優先級比它高)。ActionServlet在應用一加載時即會被實例化並調用其init方法。
(2)init方法所做的主要工作有:
①加載struts配置文件,並創建用於封裝配置信息的ModuleConfig對象
②加載資源文件,並創建用於封裝資源文件的MessageResources對象。
另外,如果有相應配置的話,init方法還將初始化數據源和PlugIn
注意:
1)如果web.xml有多模塊配置,將創建多個ModuleConfig對象和MessageResources對象分別用於封裝各個模塊的struts配置文件和資源文件。
eg. 多模塊:
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<!-- config後面的/ma表示模塊名,訪問ma模塊裡的配置文件的action中的url路徑位:應用路徑/模塊名/url.do -->
<init-param>
<param-name>config/ma</param-name>
<param-value>/WEB-INF/ma/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/mb</param-name>
<param-value>/WEB-INF/mb/struts-config.xml</param-value>
</init-param>
或者
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/catalog</param-name>
<param-value>/WEB-INF/ma-struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/authorize</param-name>
<param-value>/WEB-INF/mb-struts-config.xml</param-value>
</init-param>
2)針對各個模塊所創建的ModuleConfig對象和MessageResources對象將存儲在ServletContext中,對應的屬性名中有該模塊名稱的相應標識。
(3)ActionServlet的process()方法的主要工作有:
1)根據請求信息獲知所請求的模塊名稱,從ServletContext中獲得與請求模塊對應的的
ModuleConfig對象,並存儲到request中。
2)根據模塊信息獲得相應的RequestProcessor對象,一個模塊對應一個RequestProcessor
對象,RequestProcessor對象將關聯與所屬模塊對應的ModuleConfig對象。
3)調用RequestProcessor對象的process方法,將request和response作為參數傳遞給它。 3、RequestProcessor類
(1)Struts框架只允許應用中存在一個ActionServlet類,但每個應用程序模塊都有各自的RequestProcessor類實例。
(2)RequestProcessor對象的process方法的主要工作:
1)調用自己的 processPreprocess(request, response)方法,該方法不進行任何操作,用於
子類重寫擴展其功能。
2)獲得與請求地址所匹配的ActionMapping對象,AcionMapping對象用於封裝一個特
定acion的配置信息。
3)根據ActionMapping中的配置信息獲得ActionForm對象(該對象將緩存到request
或session中),並將表單數據填充到ActionForm中,然後根據ActionMapping的配置決
定是否驗證ActionForm,如果驗證,將調用ActionForm的validate方法,若其返回的
ActionErros對象中包含ActionMessage對象則表示驗證失敗,將轉向action配置信息input
屬性所指示的地址。
4)如果ActionForm無需驗證或驗證通過將創建並緩存與請求地址匹配的Action對象,
將ActionMapping對象、ActionForm對象、request和response作為參數調用其execute
方法。
5)根據Action對象的execute方法返回的ActionForward對象,將請求轉發或重定向到
該ActionForward所封裝的地址。
4、Action類
(1)Action類是用戶請求和業務邏輯之間的橋梁
(2)ActionServlet對所有的請求作集中的統一處理,每個不同的Action類具體處理不同的請求。
(3)每個Action類都需要實現execute()方法,RequestProcessor類創建一個Action實例後,就會調用其execute()方法。
(4)struts-config.xml:
<action-mappings>
<action path=”/ 路徑,當請求時×××.do時 FC就調用該Action的execute方法” type=”Action類的名稱(包名.類名)”name=”該Action關聯的ActionForm的名稱”
<!--如果有,則FC在調用execute方法之前要獲得ActionForm對象(第一次調用該Action時創建,然後從request或者session)並且用請求參數對其填充,然後將(ActionForm對象)作為參數調用execute方法 -->
attribute=” 緩存ActionForm對象的名稱(key),不寫key就是name的值” scope=” 緩存ActionForm的范圍(request|session)默認是session” validate=”是否要驗證true|false”
<!--如果是true,則FC在填充ActionForm之後,調用Action的execute之前,會驗證該ActionForm對象(一種是調用validate方法,另外一種是使用validation框架)-->
input=”” 和validate=”true” 聯用,表示驗證失敗後,FC把請求轉向的地址 parameter=”” 是一個附加的屬性,對於不同的Action可能有不同的意義
<!--封裝該Action可能轉發(重定向)的地址信息-->
<forward name=”” 該forward的名稱(用於mapping.findForward方法) path=”” 地址必須以“/”開頭 redirect=”” 表示是否重定向/>
… … …
</ action >
</action-mappings>
5、內置的Struts Action類
(1)目的
1)減少Action類的數目
2)便於代碼的維護
(2)DispatchAction
1)特點:
①DispatchAction 類是Action 類的子類;
②共享同一個Action 的路徑;
③共享一個ActionForm,多個不同action path,可以在同一個類中。
2)DispatchAction 的寫法:
public class MyDispatchAction extends DispatchAction{ActionForward login(ActionForm form,HttpServletRequest request,HttpServletResponse response,ActionMapping mapping)throws Exception {
return mapping.findForward(“sucess”);
}
}
注意:不要覆蓋execute()方法
3)DispatchAction 的配置文件:
<action path="/dispatch" type=" MyDispatchAction " parameter="method">
<forward name="sucess" path="/ message.jsp "/>
</action>
注意:parameter 屬性是和表單中隱藏域的名字相對應的
4)DispatchAction 頁面:
<form action=“${pageContext.request.contextPath}/dispatch.do" method="post">
<input type="hidden" name="method" value=“login"/>
<!--、使用隱藏域為struts 傳遞要調用的自定義Action 中方法的名字,通過與strutsconfig.xml 中action 標簽的parameter 屬性相對應來獲取隱藏域的value。-->
<input type="submit" value="submit"/>
</form>
<a href="${pageContext.request.contextPath}/dispatch.do?method=login">Login</a>
(3)MappingDispatchAction
1)特點:
① MappingDispatchAction 類是DispatchAction 的子類
②可以匹配多個action 路徑
③可以不共享同一個ActionForm
2)MappingDispatchAction 的寫法
public class MyMappingDispatchAction extends MappingDispatchAction{
ActionForward login(ActionForm form,HttpServletRequest request,
HttpServletResponse response,ActionMapping mapping) throws Exception{
return mapping.findForward(“success")
}
}
3)MappingDispatchAction 的配置文件
<action path="/mapping/login" type=" MyMappingDispatchAction "
parameter=“login">
<forward name=“success" path="/message.jsp"/>
</action>
注意:parameter 屬性是指定調用方法的名字
4)MappingDispatchAction 頁面
<form action=“${pageContext.request.contextPath}/mapping/login.do" method="post">
<input type="submit" value="submit"/>
</form>
注意:在JSP 頁面中不需要再使用隱藏域來傳遞參數了,在form 中的action 就可以
直接使用xxx.do 匹配了。
(4)LookupDispatchAction
1)特點:
①LookupDispatchAction 類也是DispatchAction 類的子類。
②解決一個表單的多個同名提交按鈕的問題。
③通過使用資源文件,用submit 按鈕的value 來作為資源文件中的key 所對應的值,通
過這個值來找到對應的key,再使用這個key 來獲得指定Map 中所對應的值,這個值就
是要調用的方法名。
注意:在繼承LookupDispatchAction 時,要覆蓋getKeyMethodMap()方法,並定義Map,
向Map 中放入指定的鍵值對。
2)LookupDispatchAction 的寫法
public class TestLookupDispatchAction extends LookupDispatchAction {
public ActionForward login(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception{
return mapping.findForward("success");
}
public ActionForward register(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception{
return mapping.findForward("register");
}
public Map getKeyMethodMap() {
Map map = new HashMap();
//key 為資源文件的key 值,value 為action 中的方法名。
map.put("submit.login", "login");
map.put("submit.register", "register");
return map;
}
}
3)LookupDispatchAction 資源文件
MessageResource.properties文件中?
submit.login=login
submit.register=register
4)LookupDispatchAction 的配置文件:
<form-beans >
<form-bean name="lookupForm" type="form.LookupForm" />
</form-beans>
<action-mappings>
<action path="/lookup" name="lookupForm"
type="action.TestLookupDispatchAction" parameter="submit">
<forward name="success" path="/jsp/success.jsp"/>
<forward name="register" path="/jsp/register.jsp"/>
</action>
</action-mappings>
<message-resources parameter="MessageResource" />
5)LookupDispatchAction 頁面:
<html:form action="/lookup" styleId="lookupForm"
styleClass="lookupForm">
userName:<html:text property="name" /><br>
password:<html:password property="pwd" redisplay="false" />
<br> <br>
<html:submit property="submit">
<bean:message key="submit.login" />
</html:submit>
<html:submit property="submit">
<bean:message key="submit.register" />
</html:submit>
</html:form>
注意:頁面中的property="submit"與struts-config.xml中action的parameter元素值相同
四、ActionForm
1、為什麼使用form?
(1)用戶提交的數據封裝成對象
(2)表單數據的緩存。
(3)表單信息驗證(服務器端驗證)
2、ActionForm的生命周期
(1)ActionForm Bean有兩種存在范圍:request和session
1)如果存在於request范圍,它僅在當前的請求/響應生命周期中有效
2)如果存在於session范圍,同一個ActionForm實例在整個Http會話中有效
注意:在struts配置文件中,<action>元素的scope屬性用來設置ActionForm的范圍,
默認值為session。
3、配置ActionForm
(1)action和form的關系是:一對多
(2)struts-config.xml
<form-beans>
<form-bean name="userForm" type="form.UserForm"/>
… … …
</form-beans>
(3)在某一個Action的配置中可以寫:
<action path="/add" type="action.AddUserAction" name="userForm"/>
4、Form驗證
(1)驗證:
1)表單級驗證:(不訪問數據庫)
①JavaScript做的是客戶端驗證,可以減少服務器端的負擔,但不夠安全
②在服務器端的Form驗證避免跳過客戶端的校驗
2)業務邏輯驗證:
由Action負責完成
(2)validator()方法
1)調用的條件:
①Form繼承ActionForm,並且為ActionForm配置了Action映射,即<form-bean>元素的name屬性和<action>元素的name屬性匹配。
②<action>元素的validate屬性為true
2)validate()方法
該方法返回ActionErrors對象,如果返回的ActionErrors對象為null,或者
不包含任何ActionMessage對象,就表示沒有錯誤,數據驗證通過。如果ActionErrors中包含ActionMessage對象,就表示發生了驗證錯誤。
3)validate()方法主要負責檢查數據的格式和語法,而不負責數據是否符合業務邏輯。
(3)Validator框架(驗證框架)
1)validate()方法驗證的局限性:
①必須通過程序代碼來實現驗證邏輯,如果驗證邏輯發生變化,必須重新編寫和編譯
程序代碼
②當系統中有多個ActionForm Bean,並且它們包含一些相同的驗證邏輯時,開發人員必須對每個ActionForm Bean進行重復編程,完成相同的驗證邏輯,這會降低代碼的可重用性。
2)主要依賴的jar文件:
①jakart-oro.jar:提供了一組處理文本的類,具有文本替換、過濾和分割等功能
②commons-validator.jar:提供了一個簡單、可擴展的驗證框架,包含了通用的驗證方
法和驗證規則。
3)條件:
①validator-rules.xml validation.xml
②struts-config.xml 寫plug-in
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,
/WEB-INF/validation.xml"/>
</plug-in>
③Form必須繼承ValidatorForm(ActionForm子類)
4)validator-rules.xml中規定了常見的驗證需求。一般不需要改變。
5)validation.xml是form驗證的配置文件。
<form-validation>
<formset>
<form name="需要驗證的form的名,如果有attribute屬性重命名,此處
使用重命名。">
<field property="name" depends="required">
<!--property屬性表示要驗證的form對象的屬性名-->
<!--depends屬性表示要適用的驗證邏輯(required是validator-rules.xml中規
定的驗證方式。)
如果depends屬性包含多個驗證規則,則用“,”隔開。
如果調用depends屬性指定的驗證規則時驗證失敗,就不會再調用下
一個規則。-->
<arg0 key="form.username" />
<!-- validator-rules.xml中的每一個驗證邏輯 都對應res文件中的key(key所對應的值是出錯信息) 但是出錯信息有占位符({0},{1},{2},…), arg0表示填充出錯信息中,{0}占位符的信息…
注意:實際填充的是key所指字符串在res文件中所對應的值-->
</field>
</form>
</formset>
</form-validation>
切記:Validator框架不能用於驗證標准的ActionForm類。如果要使用Validator框架,
應該采用ActionForm類的兩個子類:DynaValidatorForm(支持動態ActionForm)和ValidatorForm(支持標准ActionForm)。
5、動態ActionForm
(1)ActionForm 的缺點:表單的改動會觸發FormBean 的大量改動(應用程序停器,而且
FromBean 維護量大)。
(2)動態FormBean 是指,Struts 已提供給我們DynaActionForm(是ActionForm 的子類),我們只需通過配置文件進行配置。
(3)DynaActionForm的寫法:
①struts-config.xml
<form-bean name="dynaActionForm"
type="org.apache.struts.action.DynaActionForm">
<form-property name="name" type="java.lang.String" />
<form-property name="age" type="java.lang.Integer"/>
</form-bean>
注意:Type 表示屬性類型,注意若為基本類型時要用其包裝類。
<action path="/dyna" name="dynaActionForm"
type="action.TestDynaActionFormAction" scope="request">
<forward name="success"
path="/jsp/testDynaActionForm_success.jsp"></forward>
</action>
②TestDynaActionForm.jsp
<h1> 測試DynaActionForm</h1>
<hr>
<form action="dyna.do" method="post">
姓名:<input type="text" name="name"/> <br>
年齡:<input type="text" name="age" /> <br>
<input type="submit" value="保存"> <br>
</form>
③TestDynaActionFormAction.java
public class TestDynaActionFormAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping,
ActionForm form,HttpServletRequest request,
HttpServletResponse response) throws Exception {
DynaActionForm daf = (DynaActionForm) form;
String name = (String)daf.get("name");
//取daf中的值
Integer age = (Integer)daf.get("age");
System.out.println("name:" + name + " <===> age:" + age);
return mapping.findForward("success");
}
}
④testDynaActionForm_success.jsp(取DynaActionForm的值)
<center>
<h1>測試動態ActionForm</h1>
<hr>
姓名:${dynaActionForm.map.name } <br>
年齡:${dynaActionForm.map.age }<br>
</center>
(3)訪問動態ActionForm 與訪問普通ActionForm 的最大區別:屬性的訪問方式不同。
1)普通ActionForm—— getter setter 方法。
2)動態ActionForm—— DynaActionForm 把所有屬性保存在Map 中。
public Object get(String name)
public void set(String name, Object value)
注意:DynaActionForm 的校驗不太方便。需要繼承DynaActionForm,但是寫了代碼又不能滿足動態的功能了。
五、異常處理:
1、處理流程:
(1)Action ? throw Exception
(2)Action Servlet ? ExceptionHandler
(3)ExceptionHandler 處理Exception ExceptionHandler 會讀配置文件
ActionMessage -> request Attribute
ActionForward
(4)ActionServlet ActionForward
2、配置struts 的異常處理
全局的異常處理
<global-exceptions>
<exception key="error" path="xxx/xxx" type="xxx.xxx.Xxxx">
</global-exceptions>
<action path="xxx/xxx" type="xxx.xxx.Xxxx">
....
<exception key="xxx" path="xxx/xxx" type="xxx.xxx.Xxxx">
</action>
在exception 標簽中的key,也就是在出現異常時會封裝在ActionErrors 中,也就是可以在頁面中使用。
ActionError(String key, Object value0),可以通過在構造ActionError 時,指定不同的key 值來對異常進行分類,並且在html:error 標簽的自己構造ActionErrors 並使用下面的方法發送void saveErrors(HttpServletRequest request,ActionErrors errors)這個方法用以把封裝了異常的ActionErrors 的key 存儲到request 中。
六、Struts標簽庫
1、html標簽庫
(1)<html:form> 對應html 中的<form>,使用<html:form>會將表單中的屬性自動封裝成Form,他的action屬性可以直接寫struts 的配置文件中的path
(2)<html:text>、<html:password>、<html:textarea>、<html:hidden>、<html:submit>
<html:reset>、<html:checkbox>、<html:radio>、<html:select>、<html:option>
以上者寫標簽的使用是和html 中的form 相對應的。
(3)<html:options>這個標簽用來表示一組選擇項
<%
java.util.ArrayList list=new java.util.ArrayList();
list.add(new org.apache.struts.util.LabelValueBean("show value","value"));
list.add(new org.apache.struts.util.LabelValueBean("show value1","value1"));
pageContext.setAttribute("vlauelist" list);
%>
<html:form action="xxx.do">
<html:select property="test">
<html:options collection="valuelist" property="value" labelProperty="label"/>
</html:select>
</html:form>
2、Bean標簽庫
(1)bean 標簽庫,是用來訪為JavaBean 的屬性或者是為Bean 的屬性賦值,創建JavaBean,類似於JSP 中的jsp:useBean 動作的功能。
(2)bean 標簽庫中的標簽中大部分都有以下的屬性:
1)id="xxx" 指定Bean 的名字標識,Bean 在被讀出後將引用保存在以這個id 命名的對象中,也就是在JSP 中使用的變量的引用。
2)name="xxxx"指定要讀取Bean 的名字
3)property="xxxx"
4)scope="page|request|session|application"
(3)資源讀取標簽
1)<bean:resource>讀取資源文件
2)<bean:cookie>使用這個標簽可以對Cookie 進行操作
3)<bean:header>讀取header 信息
eg.
<bean:resource id="indexpage" name="index.jsp"/>
<bean:write name="indexpage"/>
<bean:head id="head" name="user-agent"/>
<bean:write name="head"/>
<bean:cookie id="testcookie" name="/taglib/bean-cookie" value="emptyValue"/>
<%
if(testcookie.getValue.equals("emptyValue")){
javax.servlet.http.Cookie cook=
new javax.servlet.http.Cookie("/taglib/beancookie","taglib cookie");
cook.setComment("test");
cook.setMaxAge(3600);
response.addCookie(cook);
}
%>
(4)將資源寫到頁面的標簽
1)<bean:write>將Bean 的屬性加入到輸出流中
<bean:write name="xxx"/>name 屬性是要加入的資源,也就是先前在其他資源標簽中的
id 屬性定義的名字
2)<bean:define>定義變量
eg.
<bean:define id="test" value="test in Struts">
<bean:write name="test"/>
3)<bean:message>讀取消息,可以根據key 讀取消息。
eg.
<bean:message key="org.test">
七、Struts的Token(令牌)機制
1、Struts 使用Token 機制,來防止惡意的破壞和重復提交問題,也就是點擊後退後在再提
交,這是Struts 無法發現的,在form 中生成一個token 碼,在session 中也保存有一個同樣
的token 碼,當表單提交後,判斷兩個token 碼向等後,就會改變session 中的這個token 碼,
當然在用回退後,form 的token 碼是不會變的,在提交,還會判斷兩個token 碼是否相等,
如果不等就會拋出異常,證明這是過時的垃圾數據。
2、方法:
(1)void saveToken(HttpServletRequest request)方法用於將在客戶端生成的token 碼,保存在session 中。
(2)void resetToken(HttpServletRequest request)方法用於重置token 碼,生成新的token 碼。
(3)boolean isTokenValid(HttpServletRequest request,boolean reset)判斷token 碼是否相等,並且是否重置token 碼。reset 是設定是否重置token 碼,一般設為true。
3、設置token 碼
public ActionForward toadd(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception{
saveToken(request);
return mapping.findForward("next");
}
4、驗證token 碼
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)throws Exception{
if(isTokenValid(request, true)){
request.setAttribute("message", "contratulation!");
} else {
request.setAttribute("message", "sorry");
}
return mapping.findForward("next");
}
注意:在使用Struts 的Token 時需要講JSP 頁面的<form/>標簽改成<html:form/>標簽
八、Tiles框架
1、Tiles 是一個框架,他實現了頁面的復合視圖,頁面代碼中不僅有數據,也有頁面的布局格式。
2、要在基於Struts 應用中使用Tiles 框架,就要在struts-config.xml 中配置
<plugin className="org.apache.struts.tiles.TilesPlugin">
<set-property property="definintions-config"
value="/WEB-INF/tiles-defs.xml">
<!--定義tiles 布局文件tiles-defs.xml-->
</plugin>
3、 tiles 的布局配置文件tiles-defs.xml
<tiles-definitions>
<!-- 頁面基本布局-->
<definition name="pms_base" path="/common/pms_layout.jsp">
<put name="title" value="pms title" />
<put name="header" value="/common/header.jsp" />
<put name="body" value="some body page" />
<put name="footer" value="/common/footer.jsp" />
</definition>
<!-- 其他頁面定義-->
<definition name="add" extends="pms_base">
<put name="title" value="add" />
<put name="body" value="/person_add.jsp" />
</definition>
</tiles-definitions>
4、在struts-config.xml 中要把forward 的配置更改一下
<action path="/person/toadd" type="alan.pms.action.PersonAction"
name="personForm" scope="request" parameter="toAdd">
<forward name="add" path="add"/>
</action>
這樣就會使頁面加上header.jsp 和footer.jsp 顯示在配置好的頁面中
5、在頁面中使用tiles 標簽時, 要引入標簽庫,
<%@taglib uri="/WEB-INF/tiles.tld" prefix="tiles"%>
<tiles:insert page="xxx.jsp">
<tiles:put name="header" value="header.jsp">
<tiles:put name="footer" value="footer.jsp">
</tiles:insert>
在struts-config.xml 中要把forward 的配置更改一下
<action path="/person/toadd" type="alan.pms.action.PersonAction"
name="personForm" scope="request" parameter="toAdd">
<forward name="add" path="add"/>
</action>