Struts 2 實(shí)現(xiàn)Action的幾種方式
Action用于處理用戶的請(qǐng)求,因此也被稱為業(yè)務(wù)控制器。每個(gè)Action類就是一個(gè)工作單元,Struts 2框架負(fù)責(zé)將用戶的請(qǐng)求與相應(yīng)的Action匹配,如果匹配成功,則調(diào)用該Action類對(duì)用戶請(qǐng)求進(jìn)行處理,而匹配規(guī)則需要在Struts 2的配置文件中聲明。
Struts 2框架下實(shí)現(xiàn)Action類有以下三種方式:
- 普通的POJO類,該類通常包含一個(gè)無(wú)參數(shù)的execute()方法,返回值為字符串類型。
- 實(shí)現(xiàn)Action接口
- 繼承ActionSupport類
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) {
// 返回成功頁(yè)面
return "ok";
} else {
// 返回失敗頁(yè)面
return "error";
}
}
}
登錄頁(yè)面:
<%@ 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>
錯(cuò)誤頁(yè)面:
<%@ 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>錯(cuò)誤頁(yè)面</title>
</head>
<body>
登錄失??!
</body>
</html>
成功頁(yè)面:
<%@ 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">
<!-- 定義一個(gè)名為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)了一個(gè)Action,當(dāng)單擊“登錄按鈕時(shí)”,表單中的數(shù)據(jù)會(huì)提交給login.action,Struts 2框架將自動(dòng)調(diào)用LoginAction的setter方法將請(qǐng)求參數(shù)值封裝到對(duì)應(yīng)的屬性中,并執(zhí)行execute()方法。
實(shí)現(xiàn)Action接口方式
為了讓Action類更規(guī)范,使各個(gè)開發(fā)人員編寫的execute()方法返回的字符串風(fēng)格是一致的,Struts 2提供一個(gè)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接口來(lái)創(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) {
// 返回成功頁(yè)面
return SUCCESS;
} else {
// 返回失敗頁(yè)面
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">
<!-- 定義一個(gè)名為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接口提供了一個(gè)實(shí)現(xiàn)類ActionSupport,該類提供了許多默認(rèn)方法,寫Action類時(shí)繼承ActionSupport類會(huì)大大簡(jiǎn)化Action的開發(fā)。ActionSupport類是Struts 2默認(rèn)的Action處理類,如果配置Action類時(shí)沒有指定class屬性,系統(tǒng)自動(dòng)默認(rèn)使用ActionSupport類作為Action的處理類。
下面代碼通過(guò)繼承ActionSupport類來(lái)創(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) {
// 返回成功頁(yè)面
return SUCCESS;
} else {
// 返回失敗頁(yè)面
return ERROR;
}
}
// 重寫validate()方法
public void validate() {
// 簡(jiǎn)單驗(yàn)證用戶輸入
if (this.userName == null || this.userName.equals("")) {
// 將錯(cuò)誤信息寫入到Action類的FieldErrors中
// 此時(shí)Struts 2框架自動(dòng)返回INPUT視圖
this.addFieldError("userName", "用戶名不能為空!");
System.out.println("用戶名為空!");
}
if (this.password == null || this.password.length() < 6) {
this.addFieldError("password", "密碼不能為空且密碼長(zhǎng)度不能小于6");
System.out.println("密碼不能為空且密碼長(zhǎng)度不能小于6!");
}
}
}
上述代碼增加了一個(gè)對(duì)表單提交的數(shù)據(jù)進(jìn)行驗(yàn)證的validate()方法,該方法會(huì)在執(zhí)行execute()方法之前運(yùn)行,如果發(fā)現(xiàn)表單提交數(shù)據(jù)不符合要求,則執(zhí)行addFieldError()方法,將錯(cuò)誤信息寫入Action類的字段錯(cuò)誤列表FieldErrors中,并且將自動(dòng)返回到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">
<!-- 定義一個(gè)名為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)證不通過(guò)時(shí),則會(huì)返回到輸入頁(yè)面,程序會(huì)依然“停留”(看起來(lái)是這樣,但其實(shí)是一個(gè)新的輸入頁(yè)面)在輸入頁(yè)面login.jsp。
訪問(wèn)ActionContext
相對(duì)于Struts1,Struts 2的一個(gè)重要改進(jìn)是使Action不再和任何Servlet API耦合,但有些時(shí)候Action類不訪問(wèn)Servlet API是不能實(shí)現(xiàn)業(yè)務(wù)邏輯的(例如跟蹤HTTP Session的狀態(tài))。此時(shí)Action就需要訪問(wèn)Servlet API中的HttpSession。
Struts 2提供了一種更加輕松的方式來(lái)訪問(wèn)Servlet API。在Struts 2框架中,Action可以通過(guò)ActionContext類來(lái)訪問(wèn)Servlet API,ActionContext提供了讀寫Servlet API中的HttpServletRequest、HttpSession和ServletContext中數(shù)據(jù)的方法。
常用方法如下表所示:
| 方法 | 功能描述 |
|---|---|
| Object get(Object key) | 獲取屬性值,與HttpSevletRequest的getAttribute(String name)類似 |
| Map getApplication() | 返回一個(gè)Map對(duì)象,該對(duì)象模擬了Web應(yīng)用對(duì)應(yīng)的ServletContext對(duì)象 |
| static ActionContext getContext() | 靜態(tài)方法,用于獲取系統(tǒng)的ActionContext對(duì)象 |
| Map getParameters() | 獲取所有的請(qǐng)求參數(shù),類似于調(diào)用HttpSevletRequest對(duì)象的getParameterMap()方法 |
| Map getSession() | 返回一個(gè)Map對(duì)象,該對(duì)象模擬了HttpSession實(shí)例 |
| void setApplication(Map application) | 直接傳入一個(gè)Map對(duì)象,并將該Map對(duì)象中的鍵/值對(duì)轉(zhuǎn)換成application的屬性名和屬性值 |
| void setSession(Map session) | 直接傳入一個(gè)Map對(duì)象,并將該Map對(duì)象中的鍵/值對(duì)轉(zhuǎn)換成session的屬性名和屬性值 |
下面代碼演示Action訪問(wèn)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對(duì)象,通過(guò)該對(duì)象訪問(wèn)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對(duì)象,再調(diào)用ActionContext對(duì)象的getApplication()方法獲取ServletContext對(duì)應(yīng)的Map對(duì)象,然后調(diào)用get()/put()方法進(jìn)行數(shù)據(jù)的讀/寫操作。最后將num值保存到ServletContext中。
編寫clickNum.jsp 頁(yè)面,對(duì)application進(jìn)行訪問(wèn):
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>點(diǎn)擊次數(shù)統(tǒng)計(jì)</title>
</head>
<body>
<form action="clicknum.action" method="post">
<input type="submit" value="點(diǎn)擊!" />
</form>
<!--輸出點(diǎn)擊次數(shù) -->
點(diǎn)擊按鈕,已點(diǎn)擊了
<!-- 通過(guò)表達(dá)式訪問(wèn)ServletContext對(duì)象的屬性 -->
${empty applicationScope.num?0:applicationScope.num} 次
</body>
</html>
上述代碼創(chuàng)建了一個(gè)表單,表單的action屬性值為clicknum,action,當(dāng)單擊“提交”按鈕時(shí)會(huì)將表單提交給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">
<!-- 定義一個(gè)名為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>
訪問(wèn)Servlet API
雖然Struts 2提供了ActionContext來(lái)直接訪問(wèn)Servlet API。但有時(shí)你需要直接訪問(wèn)Sevlet API。為了在Action中能夠直接訪問(wèn)Servlet API,Struts 2還提供了一系列的其他接口,通過(guò)實(shí)現(xiàn)這些接口,Action可以直接訪問(wèn)Servlet APi。
Struts 2框架提供的訪問(wèn)Servlet API的接口如下表所示:
| 方法 | 功能描述 |
|---|---|
| ServletContextAware | 實(shí)現(xiàn)該接口的Action可以直接訪問(wèn)Web應(yīng)用的SevletContext實(shí)例 |
| ServletRequestAware | 實(shí)現(xiàn)該接口的Action可以直接訪問(wèn)用戶請(qǐng)求的HttpServletRequest實(shí)例 |
| ServletResponseAware | 實(shí)現(xiàn)該接口的Action可以直接訪問(wèn)服務(wù)器響應(yīng)的HttpSevletResponse實(shí)例 |
下面代碼以實(shí)現(xiàn)SevletRequestAware接口為例,通過(guò)獲取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對(duì)象
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對(duì)象
HttpSession session = request.getSession();
//將用戶名存放到session中
session.setAttribute("CurUser", userName);
// 返回成功頁(yè)面
return SUCCESS;
} else {
// 返回失敗頁(yè)面
return ERROR;
}
}
// 重寫validate()方法
public void validate() {
// 簡(jiǎn)單驗(yàn)證用戶輸入
if (this.userName == null || this.userName.equals("")) {
// 將錯(cuò)誤信息寫入到Action類的FieldErrors中
// 此時(shí)Struts 2框架自動(dòng)返回INPUT視圖
this.addFieldError("userName", "用戶名不能為空!");
System.out.println("用戶名為空!");
}
if (this.password == null || this.password.length() < 6) {
this.addFieldError("password", "密碼不能為空且密碼長(zhǎng)度不能小于6");
System.out.println("密碼不能為空且密碼長(zhǎng)度不能小于6!");
}
}
}
上述代碼定義的LoginAction4 實(shí)現(xiàn)了SevletRequestAware接口,并且重寫該接口中setServletRequest()方法,setServletRequest()方法的參數(shù)是HttpServletRequest對(duì)象,運(yùn)行Web應(yīng)用時(shí),Struts 2框架會(huì)自動(dòng)將當(dāng)前請(qǐng)求對(duì)象傳入setServletRequest()方法,再將該請(qǐng)求對(duì)象賦給LoginAction4的request屬性,這樣在LoginAction4類的其他方法中就可以訪問(wèn)到request對(duì)象了。通過(guò)request對(duì)象可以獲取HttpSession對(duì)象,并將當(dāng)前用戶信息保存到Session中。
將login.jsp頁(yè)面中表單的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" >下一頁(yè)</a>
</body>
</html>
再創(chuàng)建一個(gè)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>
請(qǐng)求中的用戶信息:${param.userName} <br/>
Session中的用戶信息:${session.CurUser }
</body>
</html>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解在Java的Struts2框架中配置Action的方法
- ajax交互Struts2的action(客戶端/服務(wù)器端)
- struts2 action跳轉(zhuǎn)調(diào)用另一個(gè)程序
- struts2中action實(shí)現(xiàn)ModelDriven后無(wú)法返回json的解決方法
- Java的Struts框架中Action的編寫與攔截器的使用方法
- 用js模擬struts2的多action調(diào)用示例
- Struts2中Action中是否需要實(shí)現(xiàn)Execute方法
- jQuery ajax請(qǐng)求struts action實(shí)現(xiàn)異步刷新
- struts2通過(guò)action返回json對(duì)象
相關(guān)文章
SpringBoot2.x中management.security.enabled=false無(wú)效的解決
這篇文章主要介紹了SpringBoot2.x中management.security.enabled=false無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java實(shí)現(xiàn)非阻塞式服務(wù)器的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的非阻塞式服務(wù)器,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下2023-05-05
java給釘釘郵箱發(fā)送郵件功能實(shí)現(xiàn)
文章介紹了如何使用Java給釘釘郵箱發(fā)送郵件,包括開通POP和IMAP、引入pom、邏輯處理、直接添加前端傳來(lái)的MultipartFile、添加多個(gè)附件以及給多個(gè)郵箱發(fā)送郵件等步驟,感興趣的朋友一起看看吧2025-02-02
IDEA未配置SQL方言:無(wú)法使用SQL提示解決方法
在使用IDEA進(jìn)行SQL開發(fā)時(shí),如果未配置SQL方言可能會(huì)導(dǎo)致一些問(wèn)題,如無(wú)法正確識(shí)別數(shù)據(jù)庫(kù)中的關(guān)鍵字、數(shù)據(jù)類型等,這篇文章主要給大家介紹了關(guān)于IDEA未配置SQL方言,無(wú)法使用SQL提示解決方法的相關(guān)資料,需要的朋友可以參考下2024-07-07
Java Swing JProgressBar進(jìn)度條的實(shí)現(xiàn)示例
這篇文章主要介紹了Java Swing JProgressBar進(jìn)度條的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12

