Action
簡介
Action
在
MVC
模式中擔任控制部分的角色
,
在
WebWork
中使用的最多
,
用于接收頁面參數,起到對
HttpRequest
判斷處理作用。每個請求的動作都對應于一個相應的
Action
,一個
Action
是一個獨立的工作單元和控制命令,它必需要實現
XWork
里的
Action
接口,實現
Action
接口的
execute()
方法。
Action
接口的代碼如下:
package com.opensymphony.xwork;
import Java.io.Serializable;
public interface Action extends Serializable {
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
public String execute() throws Exception;
}
excute()
方法是
Action
類里最重要的部分,它執行返回
String
類型的值,代表在頁面執行完后的結果,在
Action
中返回的值一般使用它上面定義的標準靜態字符常量。它有五種狀態:
1
.
SUCCESS
:
Action
正確的執行完成,返回相應的視圖;
2
.
NONE
:表示
Action
正確的執行完成,但并不返回任何視圖;
3
.
ERROR
:表示
Action
執行失敗,返回到錯誤處理視圖;
4
.
INPUT
:
Action
的執行,需要從前端界面獲取參數,
INPUT
就是代表這個參數輸入的界面,一般在應用中,會對這些參數進行驗證,如果驗證沒有通過,將自動返回到該視圖;
5
.
LOGIN
:
Action
因為用戶沒有登陸的原因沒有正確執行,將返回該登陸視圖,要求用戶進行登陸驗證。
下面我們將以一個用戶注冊的例子詳細介紹
Action
的原理:
功能描述:一個用戶注冊頁面
register.jsp
,用戶可以在這個頁面里輸入用戶注冊的基本信息(例如:姓名、密碼、
Email
等),輸入完成提交表單,執行用戶注冊的
Action
,執行成功返回成功提示的頁面(
register-result.jsp
)并將注冊的信息輸出。
流程如下:
模型:
User.java
控制:
RegisterAction.java
視圖:
register.jsp
、
register-result.jsp
配置:
xwork.xml
User.java
:
package register;
public class User {
private String username;
private String password;
private String email;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
……
public int getAge() {
return age;
}
public int setAge(int age) {
this.age = age;
}
public String toString(){
return "username=" + username
+ ";password=" + password
+ ";email=" + email
+ ";age=" + age;
}
}
模型
User
是一個普通的
JavaBean
,它包含了用戶注冊的字段信息,并對每個字段提供相應的
set
和
get
方法。下面我們來看看進行用戶注冊動作的
RegisterAction.java
:
package
example.register;
import
com.opensymphony.xwork.Action;
/**
*@authorbabydavic-qac
* achqian@yahoo.com.cn
*/
public
class
RegisterAction
implements
Action
{
privateUseruser=newUser();
public User getUser(){
returnthis.user;
}
publicStringexecute(){
System.out.println("Start execute
。。。。。。。。。。。。。
"
);
System.out.println("User="+user);
//
在這里調用用戶注冊的業務邏輯,比如:將注冊信息存儲到數據庫
returnSUCCESS;
}
}
這個
Action
是不是特清爽?用戶注冊就這么幾行代碼搞定,當然,我們提倡在
Action
里最好不要實現業務代碼,業務代碼編寫在
service.java
里面,
Action
的主要功能是提供從請求中取得參數的值,轉化成相應的模型,再將模型傳遞給執行業務操作的對象,比如:將注冊的用戶信息存儲到數據庫中,由業務對象執行業務操作,再返回執行的結果。為了簡化我們省去了注冊的業務邏輯執行步驟
再看看我們注冊信息輸入的頁面:
register.jsp
<html>
<head><title>Register Example</title></head>
<body>
<table border=0 width=97%>
<tr><td align="left">
<form name="register" action="register.action" method="post">
Username:<input type="text" name="user.username"><br>
Password:<input type="text" name="user.password"><br>
Email:<input type="text" name="user.email"><br>
Age:<input type="text" name="user.age"><br>
<input type="submit" name="Submit"><br>
</form>
</td></tr>
</table>
</body>
</html>
register.jsp
頁面其實只是一個普通的
HTML
頁面,它提供了一個表單,用來接受用戶輸入的注冊信息,它唯一特殊的部分就是
input
輸入框定義的
name
部分,例如:用戶姓名用的是“
user. username
”。這種命名方式代表什么含義?它是必需的嗎?后面我們將會給出答案。
RegisterAction
正確執行完成之后,會將執行的結果返回到
register-result.jsp
頁面,由它來顯示用戶在前面頁面輸入的注冊信息。
register-result.jsp
代碼如下
:
<%@ taglib prefix="ww" uri="webwork" %>
<html>
<head><title>Register result</title></head>
<body>
<table border=0 width=97%>
<tr>
<td align="left">
Congratulation,your register success!<p>
Username:<ww:property value="user.username"/><br>
Password:<ww:property value="user.password"/><br>
Email:<ww:property value="user.email"/><br>
Age:<ww:property value="user.age"/><br>
</td>
</tr>
</table>
</body>
這個
Jsp
頁面使用了
WebWork
的標簽庫
<ww:property />
,記得
HelloWorld
里的
greetings.jsp
嗎?它也使用了這個標簽庫。我們看這個:
<ww:property value="user.username"/>
它是一個普通的使用標簽庫語句,查看這個標簽庫的源程序,見包
com.opensymphony.webwork.views.jsp
里的
PropertyTag.java
文件,你會發現這個類會根據
value
后面賦予的表達式值,去
OgnlValueStack
里查找這個表達式值所對應的操作。執行這個語句
OgnlValueStack
會根據
value
的值(一個表達式)“
user.username
”去分別調用
RegisterAction
類的
getUser()
和
User
類的
getUsername()
方法,即:
getUser().getUsername()
,取得的數據就是前面注冊頁面輸入的用戶名。
我們把“
user.username
”這樣的語句叫做表達式語言(
Expression Language
,簡稱為
EL
)。它由
XWork
框架提供,
XWork
表達式語言的核心是
OGNL
(
Object Graph Notation Language
),
OGNL
是一種功能強大,技術成熟,應用廣泛的表達式語言,將在下面的章節有詳細介紹。
我們在回到前面介紹的
register.jsp
,
Input
輸入框
<input type="text" name="user.username">
里用的“
user.username
”,現在我們可以明白,它不是隨意設置的,它是一個表達式語言,有著特殊的功能。看到這里,不知道你心中是否有一個疑問:我們的
RegisterAction
是如何取得用戶注冊頁面輸入的數據呢?如果你做過
Web
開發,你一定會想到
RegisterAction
里必需有一些從客戶端請求中獲取參數的語句,例如:
類似:
String username = request.getParameter(“user. username”)
的語句(
request
是
HttpServletRequest
的對象),去從
request
請求里面獲取用戶輸入的參數值。可是我們這個
Action
里面只有
User
對象簡單的
get
方法,并沒有其它的代碼。
Xwork
框架的
Action
是如何去實現了與
Web
無關?
request
請求的參數是怎么傳遞到我們
Action
的模型
User
中呢?
在回答答案之前,我們先看一看
Xwork
的配置文件
xwork.xml
:
<action
name=
"register"
class=
"example.register.RegisterAction"
>
<resultname="success"type="dispatcher">
<paramname="location">/register-result.jsp</param>
</result>
<interceptor-refname="params"/>
</action>
看了前面的介紹,這段配置文件應該不難理解。用戶通過注冊頁面
register.jsp
輸入自己的注冊信息,提交表單到動作
register.action
,它將有
ServletDispatcher
調度,從配置文件
xwork.xml
里查找與“
register
”匹配的
Action
名字,即上面配置的
Action
。通過這個名字
XWork
框架找到這個
Action
的類:
example.register.RegisterAction
,
XWork
框架會負責去創建這個
Action
類的對象并調用
execute()
方法進行用戶注冊操作。正確執行
execute()
方法返回
String
類型數據“
success
”之后,它會請求再派遣到
register-result.jsp
頁面。
在這段配置文件里,你一定注意到了它特殊的一句:
<interceptor-ref name="params"/>
,
interceptor-ref
標簽設置這個
Action
用到的攔截器
(Interceptor)
,“
params
”引用的是配置文件中的
<interceptor name="params" class="
com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
,這個攔截器將在
RegisterAction
的
execute()
方法執行之前調用,作用是將
request
請求的參數值通過表達式語言設置到相應
RegisterAction
的模型里。例如:
register.jsp
里的
<input type="text" name="user.username">
,它輸入的值會由
RegisterAction
類的
getUser()
和
User
類的
setUserName(“…”)
設置到這個
User
模型里。假設你在注冊頁面輸入用戶名“
babydavic
”,提交表單
ParametersInterceptor
就會下面的操作:首先從請求中取得參數的名字和名字對應的值,分別為:“
user.username
”和“
babydavic
”,根據這個名字,從
OgnlValueStack
中取得堆棧最上面的
getUser().setUsername(“babydavic”)
操作,即取得
RegisterAction
對象的
User
模型,并設置
username
屬性的值為“
babydavic
”。
原來,我們的
Action
是通過
XWork
的攔截器
ParametersInterceptor
從提交的表單中取得請求的參數和值,再通過
OgnlValueStack
來執行表達式,調用
Action
和模型里相應的
ge
或
set
方法,將從請求中取得的值設置到模型中去。
register.jsp
中
Input
輸入框的
name="user.username"
是必需要遵守
OGNL
的命名規則。也正是很多攔截器的使用,使得我們的
Action
類和
Web
實現了完全的解耦,讓我們的
Action
能如此的簡單、優雅,攔截器的原理后面章節我們也將會有詳細的介紹。
Action
根據
FormBean
的不同可以分為二類,
一類是
Field-Driven
(字段驅動的)
Action
Action
將直接用自己的字段來充當
FormBean
的功能,我們的例子就是使用這種方式。它一般用在頁面表單比較簡單的情況使用,而且可以直接用域對象作為
Action
的字段,這樣就不用在另寫
FormBean
,減少了重復代碼。
另一類是
Model-Driven
(模型驅動的)
Action
它很像
Struts
的
FormBean
,但在
WebWork
中,只要普通
Java
對象就可以充當模型部分。
Model-Driven
(模型驅動的)
Action
要求我們的
Action
實現
com.opensymphony.xwork. ModelDriven
接口,它有一個方法:
Object getModel();
,我們用這個方法返回我們的模型對象就可以了。
我們可以將前面的
RegisterAction.java
改為
Model-Driven
(模型驅動的)
Action
:
package
example.register;
import
com.opensymphony.xwork.Action;
import
com.opensymphony.xwork.ModelDriven;
/**
*@authormoxie-qac
* achqian@yahoo.com.cn
*
*/
public
class
RegisterActionModel
implements
Action,ModelDriven{
privateUseruser=newUser();
publicStringexecute()throwsException{
System.out.println("Start execute......
。。。。。。。。。。。。。。
"
);
System.out.println("User="+user);
//
在這里調用用戶注冊的業務邏輯,比如:將注冊信息存儲到數據庫
returnSUCCESS;
}
public Object getModel() {
return user;
}
}
這時我們輸入信息的頁面也有了變化:
register-model.jsp
<html>
<head><title>Register Example</title></head>
<body>
<table border=0 width=97%>
<tr><td align="left">
<form name="register" action="registerModel.action" method="post">
Username:<input type="text" name="username"><br>
Password:<input type="text" name="password"><br>
Email:<input type="text" name="email"><br>
Age:<input type="text" name="age"><br>
<input type="submit" name="Submit"><br>
</form>
</td></tr>
</table>
</body>
</html>
我們發現,輸入框里的命名發生了變化。它們都少了“
user.
”這部分信息。
當我們采用
Model-Driven
(模型驅動的)
Action
時,它將取得模型對象保存在值堆棧中。“
name="username"
”就是代表直接調用模型對象的
setUsername()
方法。
我們
Action
的在配置文件中,也要給它指定一個攔截器
model-driven
,
它的作用就是將模型對象保存到值堆棧中。關于攔截器的介紹請看下面的章節。
配置文件如下:
<action
name=
"registerModel"
class=
"example.register.RegisterActionModel"
>
<resultname="success"type="dispatcher">
<paramname="location">/register-result-model.jsp</param>
</result>
<interceptor-ref name="model-driven"/>
<interceptor-refname="params"/>
</action>
posted on 2006-12-13 17:28
周銳 閱讀(645)
評論(0) 編輯 收藏 所屬分類:
Webwork