您好,登錄后才能下訂單哦!
Action用于處理用戶的請求,因此也被稱為業(yè)務(wù)控制器。每個Action類就是一個工作單元,Struts 2框架負(fù)責(zé)將用戶的請求與相應(yīng)的Action匹配,如果匹配成功,則調(diào)用該Action類對用戶請求進(jìn)行處理,而匹配規(guī)則需要在Struts 2的配置文件中聲明。
Struts 2框架下實(shí)現(xiàn)Action類有以下三種方式:
POJO實(shí)現(xiàn)方式
以用戶登錄為例,創(chuàng)建LoginAction類。
package com.qst.chapter03.action; public class LoginAction { /* 用戶名 */ private String userName; /* 密碼 */ private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /** * 調(diào)用業(yè)務(wù)邏輯方法,控制業(yè)務(wù)流程 */ public String execute() { System.out.println("----登錄的用戶信息-----"); System.out.println("用戶名:" + userName); System.out.println("密碼:" + password); if (userName.startsWith("qst") && password.length() >= 6) { // 返回成功頁面 return "ok"; } else { // 返回失敗頁面 return "error"; } } }
登錄頁面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <title>用戶登錄</title> </head> <body> <form action="login.action" method="post" name="logForm"> <table> <tr> <td>用戶名</td> <td><input type="text" name="userName" size="15" /></td> </tr> <tr> <td>密碼</td> <td><input type="password" name="password" size="15" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="登錄"></td> </tr> </table> </form> </body> </html>
錯誤頁面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>錯誤頁面</title> </head> <body> 登錄失敗! </body> </html>
成功頁面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>顯示用戶信息</title> </head> <body> 登錄成功!歡迎用戶${param.userName} ! </body> </html>
struts.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 指定Struts2處于開發(fā)階段,可以進(jìn)行調(diào)試 --> <constant name="struts.devMode" value="true" /> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <!-- Struts2的Action都必須配置在package里,此處使用默認(rèn)package --> <package name="default" namespace="/" extends="struts-default"> <!-- 定義一個名為user的Action,實(shí)現(xiàn)類為com.qst.chapter03.action.LoginAction --> <action name="login" class="com.qst.chapter03.action.LoginAction3"> <!-- 配置execute()方法返回值與視圖資源之間的映射關(guān)系 --> <result name="ok">/ok.jsp</result> <result name="error">/error.jsp</result> </action> </package> </struts>
這樣就以POJO方式實(shí)現(xiàn)了一個Action,當(dāng)單擊“登錄按鈕時”,表單中的數(shù)據(jù)會提交給login.action,Struts 2框架將自動調(diào)用LoginAction的setter方法將請求參數(shù)值封裝到對應(yīng)的屬性中,并執(zhí)行execute()方法。
實(shí)現(xiàn)Action接口方式
為了讓Action類更規(guī)范,使各個開發(fā)人員編寫的execute()方法返回的字符串風(fēng)格是一致的,Struts 2提供一個Action接口,該接口定義了Acitoin處理類應(yīng)該實(shí)現(xiàn)的通用規(guī)范:
public abstract interface Action { public static final java.lang.String SUCCESS = "success"; public static final java.lang.String NONE = "none"; public static final java.lang.String ERROR = "error"; public static final java.lang.String INPUT = "input"; public static final java.lang.String LOGIN = "login"; public String execute() throws Exception; }
下面代碼使用Action接口來創(chuàng)建Action類:
package com.qst.chapter03.action; import com.opensymphony.xwork2.Action; public class LoginAction2 implements Action{ /* 用戶名 */ private String userName; /* 密碼 */ private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /** * 調(diào)用業(yè)務(wù)邏輯方法,控制業(yè)務(wù)流程 */ public String execute() { System.out.println("----登錄的用戶信息-----"); System.out.println("用戶名:" + userName); System.out.println("密碼:" + password); if (userName.startsWith("qst") && password.length() >= 6) { // 返回成功頁面 return SUCCESS; } else { // 返回失敗頁面 return ERROR; } } }
struts.xml:
<struts> <!-- 指定Struts2處于開發(fā)階段,可以進(jìn)行調(diào)試 --> <constant name="struts.devMode" value="true" /> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <!-- Struts2的Action都必須配置在package里,此處使用默認(rèn)package --> <package name="default" namespace="/" extends="struts-default"> <!-- 定義一個名為user的Action,實(shí)現(xiàn)類為com.qst.chapter03.action.LoginAction --> <action name="login" class="com.qst.chapter03.action.LoginAction3"> <!-- 配置execute()方法返回值與視圖資源之間的映射關(guān)系 --> <result name="success">/ok.jsp</result> <result name="error">/error.jsp</result> </action> </package> </struts>
繼承ActionSupport類方式
Struts 2框架為Action接口提供了一個實(shí)現(xiàn)類ActionSupport,該類提供了許多默認(rèn)方法,寫Action類時繼承ActionSupport類會大大簡化Action的開發(fā)。ActionSupport類是Struts 2默認(rèn)的Action處理類,如果配置Action類時沒有指定class屬性,系統(tǒng)自動默認(rèn)使用ActionSupport類作為Action的處理類。
下面代碼通過繼承ActionSupport類來創(chuàng)建Action類,并重寫validate()驗(yàn)證方法:
package com.qst.chapter03.action; import com.opensymphony.xwork2.ActionSupport; public class LoginAction3 extends ActionSupport { /* 用戶名 */ private String userName; /* 密碼 */ private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } /** * 調(diào)用業(yè)務(wù)邏輯方法,控制業(yè)務(wù)流程 */ public String execute() { System.out.println("----登錄的用戶信息-----"); System.out.println("用戶名:" + userName); System.out.println("密碼:" + password); if (userName.startsWith("qst") && password.length() >= 6) { // 返回成功頁面 return SUCCESS; } else { // 返回失敗頁面 return ERROR; } } // 重寫validate()方法 public void validate() { // 簡單驗(yàn)證用戶輸入 if (this.userName == null || this.userName.equals("")) { // 將錯誤信息寫入到Action類的FieldErrors中 // 此時Struts 2框架自動返回INPUT視圖 this.addFieldError("userName", "用戶名不能為空!"); System.out.println("用戶名為空!"); } if (this.password == null || this.password.length() < 6) { this.addFieldError("password", "密碼不能為空且密碼長度不能小于6"); System.out.println("密碼不能為空且密碼長度不能小于6!"); } } }
上述代碼增加了一個對表單提交的數(shù)據(jù)進(jìn)行驗(yàn)證的validate()方法,該方法會在執(zhí)行execute()方法之前運(yùn)行,如果發(fā)現(xiàn)表單提交數(shù)據(jù)不符合要求,則執(zhí)行addFieldError()方法,將錯誤信息寫入Action類的字段錯誤列表FieldErrors中,并且將自動返回到INPUT輸入視圖,讓用戶重新輸入表單并提交。
在struts.xml配置文件中增加INPUT輸入視圖:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 指定Struts2處于開發(fā)階段,可以進(jìn)行調(diào)試 --> <constant name="struts.devMode" value="true" /> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <!-- Struts2的Action都必須配置在package里,此處使用默認(rèn)package --> <package name="default" namespace="/" extends="struts-default"> <!-- 定義一個名為user的Action,實(shí)現(xiàn)類為com.qst.chapter03.action.LoginAction --> <action name="login" class="com.qst.chapter03.action.LoginAction3"> <!-- 配置execute()方法返回值與視圖資源之間的映射關(guān)系 --> <result name="success">/ok.jsp</result> <result name="error">/error.jsp</result> <result name="input">/login.jsp</result> </action> </package> </struts>
當(dāng)表單提交的數(shù)據(jù)驗(yàn)證不通過時,則會返回到輸入頁面,程序會依然“停留”(看起來是這樣,但其實(shí)是一個新的輸入頁面)在輸入頁面login.jsp。
訪問ActionContext
相對于Struts1,Struts 2的一個重要改進(jìn)是使Action不再和任何Servlet API耦合,但有些時候Action類不訪問Servlet API是不能實(shí)現(xiàn)業(yè)務(wù)邏輯的(例如跟蹤HTTP Session的狀態(tài))。此時Action就需要訪問Servlet API中的HttpSession。
Struts 2提供了一種更加輕松的方式來訪問Servlet API。在Struts 2框架中,Action可以通過ActionContext類來訪問Servlet API,ActionContext提供了讀寫Servlet API中的HttpServletRequest、HttpSession和ServletContext中數(shù)據(jù)的方法。
常用方法如下表所示:
方法 | 功能描述 |
---|---|
Object get(Object key) | 獲取屬性值,與HttpSevletRequest的getAttribute(String name)類似 |
Map getApplication() | 返回一個Map對象,該對象模擬了Web應(yīng)用對應(yīng)的ServletContext對象 |
static ActionContext getContext() | 靜態(tài)方法,用于獲取系統(tǒng)的ActionContext對象 |
Map getParameters() | 獲取所有的請求參數(shù),類似于調(diào)用HttpSevletRequest對象的getParameterMap()方法 |
Map getSession() | 返回一個Map對象,該對象模擬了HttpSession實(shí)例 |
void setApplication(Map application) | 直接傳入一個Map對象,并將該Map對象中的鍵/值對轉(zhuǎn)換成application的屬性名和屬性值 |
void setSession(Map session) | 直接傳入一個Map對象,并將該Map對象中的鍵/值對轉(zhuǎn)換成session的屬性名和屬性值 |
下面代碼演示Action訪問ActionContext的使用
package com.qst.chapter03.action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class ClickNumAction extends ActionSupport { public String execute() { // 獲取ActionContext對象,通過該對象訪問Servlet API ActionContext ctx = ActionContext.getContext(); // 獲取ServletContext里的num屬性 Integer num = (Integer) ctx.getApplication().get("num"); // 如果num屬性為null,設(shè)置num屬性為1 if (num == null) { num = 1; } else { // 將num加1 num++; } // 將加1后的num值保存在application中 ctx.getApplication().put("num", num); return SUCCESS; } }
上面代碼先使用ActionContext.getContext()靜態(tài)方法獲取系統(tǒng)的ActionContext對象,再調(diào)用ActionContext對象的getApplication()方法獲取ServletContext對應(yīng)的Map對象,然后調(diào)用get()/put()方法進(jìn)行數(shù)據(jù)的讀/寫操作。最后將num值保存到ServletContext中。
編寫clickNum.jsp 頁面,對application進(jìn)行訪問:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <title>點(diǎn)擊次數(shù)統(tǒng)計</title> </head> <body> <form action="clicknum.action" method="post"> <input type="submit" value="點(diǎn)擊!" /> </form> <!--輸出點(diǎn)擊次數(shù) --> 點(diǎn)擊按鈕,已點(diǎn)擊了 <!-- 通過表達(dá)式訪問ServletContext對象的屬性 --> ${empty applicationScope.num?0:applicationScope.num} 次 </body> </html>
上述代碼創(chuàng)建了一個表單,表單的action屬性值為clicknum,action,當(dāng)單擊“提交”按鈕時會將表單提交給CounterAction進(jìn)行處理。
在struts.xml配置文件中增加CounterAction的配置:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 指定Struts2處于開發(fā)階段,可以進(jìn)行調(diào)試 --> <constant name="struts.devMode" value="true" /> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <!-- Struts2的Action都必須配置在package里,此處使用默認(rèn)package --> <package name="default" namespace="/" extends="struts-default"> <!-- 定義一個名為user的Action,實(shí)現(xiàn)類為com.qst.chapter03.action.LoginAction --> <action name="login" class="com.qst.chapter03.action.LoginAction3"> <!-- 配置execute()方法返回值與視圖資源之間的映射關(guān)系 --> <result name="success">/ok.jsp</result> <result name="error">/error.jsp</result> <result name="input">/login.jsp</result> </action> <action name="clicknum" class="com.qst.chapter03.action.ClickNumAction"> <result name="success">/clickNum.jsp</result> </action> </package> </struts>
訪問Servlet API
雖然Struts 2提供了ActionContext來直接訪問Servlet API。但有時你需要直接訪問Sevlet API。為了在Action中能夠直接訪問Servlet API,Struts 2還提供了一系列的其他接口,通過實(shí)現(xiàn)這些接口,Action可以直接訪問Servlet APi。
Struts 2框架提供的訪問Servlet API的接口如下表所示:
方法 | 功能描述 |
---|---|
ServletContextAware | 實(shí)現(xiàn)該接口的Action可以直接訪問Web應(yīng)用的SevletContext實(shí)例 |
ServletRequestAware | 實(shí)現(xiàn)該接口的Action可以直接訪問用戶請求的HttpServletRequest實(shí)例 |
ServletResponseAware | 實(shí)現(xiàn)該接口的Action可以直接訪問服務(wù)器響應(yīng)的HttpSevletResponse實(shí)例 |
下面代碼以實(shí)現(xiàn)SevletRequestAware接口為例,通過獲取HttpSession,將登陸成功的用戶名保存到Session中:
package com.qst.chapter03.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.interceptor.ServletRequestAware; import com.opensymphony.xwork2.ActionSupport; public class LoginAction4 extends ActionSupport implements ServletRequestAware { /* 用戶名 */ private String userName; /* 密碼 */ private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } //聲明request對象 private HttpServletRequest request; //重寫ServletRequestAware中的方法 public void setServletRequest(HttpServletRequest request) { this.request = request; } /** * 調(diào)用業(yè)務(wù)邏輯方法,控制業(yè)務(wù)流程 */ public String execute() { System.out.println("----登錄的用戶信息-----"); System.out.println("用戶名:" + userName); System.out.println("密碼:" + password); if (userName.startsWith("qst") && password.length() >= 6) { // 獲得session對象 HttpSession session = request.getSession(); //將用戶名存放到session中 session.setAttribute("CurUser", userName); // 返回成功頁面 return SUCCESS; } else { // 返回失敗頁面 return ERROR; } } // 重寫validate()方法 public void validate() { // 簡單驗(yàn)證用戶輸入 if (this.userName == null || this.userName.equals("")) { // 將錯誤信息寫入到Action類的FieldErrors中 // 此時Struts 2框架自動返回INPUT視圖 this.addFieldError("userName", "用戶名不能為空!"); System.out.println("用戶名為空!"); } if (this.password == null || this.password.length() < 6) { this.addFieldError("password", "密碼不能為空且密碼長度不能小于6"); System.out.println("密碼不能為空且密碼長度不能小于6!"); } } }
上述代碼定義的LoginAction4 實(shí)現(xiàn)了SevletRequestAware接口,并且重寫該接口中setServletRequest()方法,setServletRequest()方法的參數(shù)是HttpServletRequest對象,運(yùn)行Web應(yīng)用時,Struts 2框架會自動將當(dāng)前請求對象傳入setServletRequest()方法,再將該請求對象賦給LoginAction4的request屬性,這樣在LoginAction4類的其他方法中就可以訪問到request對象了。通過request對象可以獲取HttpSession對象,并將當(dāng)前用戶信息保存到Session中。
將login.jsp頁面中表單的action屬性改成login4.action:
... <form action="login.action" method="post" name="logForm"> ...
創(chuàng)建first.jsp顯示用戶信息:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>顯示用戶信息</title> </head> <body> 登錄成功!歡迎用戶${param.userName} <br/> 當(dāng)前用戶${session.CurUser } <br/> <a href="second.jsp" rel="external nofollow" >下一頁</a> </body> </html>
再創(chuàng)建一個second.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>顯示用戶信息</title> </head> <body> 請求中的用戶信息:${param.userName} <br/> Session中的用戶信息:${session.CurUser } </body> </html>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。