webwork(二)--用戶註冊實例

 

HelloWorld

  首先看下面這個程序HelloWorldAction.java:

CODE:

package helloWorld

import com.opensymphony.xwork.Action;

public class HelloWorldAction implements Action{

     String greeting;

     public String getGreeting() {

 return greeting;

     }

     public String execute() throws Exception {

 greeting = "Hello World!";

 return SUCCESS;

     }

}

[Copy to clipboard]

  HelloWorldAction是一個普通的Java類,它實現了Action這個接口。Action是一個非常簡單的接口,只有一個方法:public String execute() throws Exception; ,Action類介紹見下一節。HelloWorldAction有一個String類型字段greeting,在execute()方法中,greeting被賦值“Hello World!”,並返回String型常量SUCCESS,SUCCESS的定義詳見Action接口,這個常量代表了execute()方法執行成功,將返回成功頁面。

  返回的頁面greetings.jsp代碼如下:

CODE:

<%@ taglib prefix="ww" uri="webwork" %>

<html>

     <head>

 <title>First WebWork Example</title>

     </head>

     <body>

 <p><ww:property value="greeting"/></p>

     </body>

</html>

[Copy to clipboard]

  greetings.jsp很簡單的jsp頁面,它使用了WebWork自帶的標籤庫。它的作用是輸出變量“greeting”的值。這個<ww:property value="greeting"/>語句,相當於調用相應Action(HelloWorldAction)的getGreeting()方法,取得變量“greeting”的值。

  我們的HelloWorld代碼就這麼多,完了。可是,HelloWorldAction怎麼去調用、執行?執行成功它又怎麼知道返回到greetings.jsp?XWork的配置文件xwork.xml會負責將要執行的Action和展現的視圖連接起來,見xwork.xml的如下片斷:

CODE:

<action name="hello" class=" helloWorld .HelloWorldAction">

     <result name="success" type="dispatcher">

 <param name="location">/greetings.jsp</param>

     </result>

</action>

[Copy to clipboard]

  我們先看action標籤:name=”hello”,表示我們調用這個Action的標識是hello,這樣我們可以通過下面的url訪問這個Action:…/hello.action,

例如:http://localhost:8080/webwork/hello.action;class=" helloWorld .HelloWorldAction"很好理解,這是真正調用執行的類。我們在看看result標籤:name="success",記得前面HelloWorldAction返回的字符常量SUCCESS嗎?它的值其實就是“success”,它表示Action執行成功返回success就轉向這個結果;type="dispatcher"表示執行完Action,轉向結果頁面的方式;param參數指定了結果頁面的位置:/greetings.jsp。

  代碼寫完,剩下的當然是編譯、部署。啓動tomcat服務器之後我們就可以執行了:

  在瀏覽器裏輸入你的地址:http://localhost:8080/webwork/hello.action

  你將會看到如下結果:

Action(動作)

Action介紹

  Action在MVC模式中擔任控制部分的角色,在WebWork中使用的最多。每個請求的動作都對應於一個相應的Action,一個Action是一個獨立的工作單元和控制命令,它必需要實現XWork裏的Action接口,實現Action接口的execute()方法。Action接口的代碼如下:

CODE:

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;

}

[Copy to clipboard]

  excute()方法是Action類裏最重要的部分,它執行返回String類型的值,在Action中返回的值一般使用它上面定義的標準靜態字符常量。例如:前面的HelloWorldAction返回的就是SUCCESS字符常量,真正的值當然就是“success”,它與xwork配置文件裏result標籤name的值是相對應的。它用來決定execute()方法執行完成之後,調用哪一種返回結果。字符常量的含義如下:

  SUCCESS:Action正確的執行完成,返回相應的視圖;

  NONE:表示Action正確的執行完成,但並不返回任何視圖;

  ERROR:表示Action執行失敗,返回到錯誤處理視圖;

  INPUT:Action的執行,需要從前端界面獲取參數,INPUT就是代表這個參數輸入的界面,一般在應用中,會對這些參數進行驗證,如果驗證沒有通過,將自動返回到該視圖;

  LOGIN:Action因爲用戶沒有登陸的原因沒有正確執行,將返回該登陸視圖,要求用戶進行登陸驗證。

用戶註冊例子

  下面我們將以一個用戶註冊的例子詳細介紹Action的原理:

  功能描述:一個用戶註冊頁面register.jsp,用戶可以在這個頁面裏輸入用戶註冊的基本信息(例如:姓名、密碼、Email等),輸入完成提交表單,執行用戶註冊的Action,執行成功返回成功提示的頁面(register-result.jsp)並將註冊的信息輸出。

  模型:User.java

  控制:RegisterAction.java

  視圖:register.jsp、register-result.jsp

  配置:xwork.xml

  User.java:

CODE:

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;

     }

}

[Copy to clipboard]

  模型User是一個普通的JavaBean,它包含了用戶註冊的字段信息,並對每個字段提供相應的set和get方法。下面我們來看看進行用戶註冊動作的RegisterAction.java:

CODE:

package example.register;

import com.opensymphony.xwork.Action;

/**

* @author moxie-qac

*         [email protected]

*/

public class RegisterAction implements Action {

     private User user= new User();

     public User getUser() {

 return this.user;

     }

     public String execute() {

 System.out.println("Start execute 。。。。。。。。。。。。。");

 System.out.println("User="+user);

 //在這裏調用用戶註冊的業務邏輯,比如:將註冊信息存儲到數據庫

 return SUCCESS;

     }

}

[Copy to clipboard]

  這個Action是不是特清爽?用戶註冊就這麼幾行代碼搞定,當然,我們提倡在Action裏最好不要實現業務代碼,Action的主要功能是提供從請求中取得參數的值,轉化成相應的模型,再將模型傳遞給執行業務操作的對象,比如:將註冊的用戶信息存儲到數據庫中,由業務對象執行業務操作,再返回執行的結果。爲了簡化我們省去了註冊的業務邏輯執行步驟。

  再看看我們註冊信息輸入的頁面:register.jsp

CODE:

<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>

[Copy to clipboard]

  register.jsp頁面其實只是一個普通的HTML頁面,它提供了一個表單,用來接受用戶輸入的註冊信息,它唯一特殊的部分就是input輸入框定義的name部分,例如:用戶姓名用的是“user. username”。這種命名方式代表什麼含義?它是必需的嗎?後面我們將會給出答案。

  RegisterAction正確執行完成之後,會將執行的結果返回到register-result.jsp頁面,由它來顯示用戶在前面頁面輸入的註冊信息。register-result.jsp代碼如下:

CODE:

<%@ 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>

</html>

[Copy to clipboard]

  這個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:

  

CODE:

<action name="register" class="example.register.RegisterAction" >

     <result name="success" type="dispatcher">

 <param name="location">/register-result.jsp</param>

     </result>

     <interceptor-ref name="params"/>

</action>

[Copy to clipboard]

  看了前面的介紹,這段配置文件應該不難理解。用戶通過註冊頁面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模型裏。假設你在註冊頁面輸入用戶名“moxie”,提交表單ParametersInterceptor就會下面的操作:首先從請求中取得參數的名字和名字對應的值,分別爲:“user.username”和“moxie”,根據這個名字,從OgnlValueStack中取得堆棧最上面的getUser().setUsername(“moxie”)操作,即取得RegisterAction對象的User模型,並設置username屬性的值爲“moxie”。

  原來,我們的Action是通過XWork的攔截器ParametersInterceptor從提交的表單中取得請求的參數和值,再通過OgnlValueStack來執行表達式,調用Action和模型裏相應的ge或set方法,將從請求中取得的值設置到模型中去。register.jsp中Input輸入框的name="user.username"是必需要遵守OGNL的命名規則。也正是很多攔截器的使用,使得我們的Action類和Web實現了完全的解耦,讓我們的Action能如此的簡單、優雅,攔截器的原理後面章節我們也將會有詳細的介紹。

  羅索了這麼多,你一定是精通了這個用戶註冊的例子了吧!呵呵!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章