|
表達式與言EL和OGNL OGNL介紹 OGNL是Object-Graph Navigation Language的縮寫,它是一種功能強大的表達式語言(Expression Language,簡稱為EL),通過它簡單一致的表達式語法,可以存取對象的任意屬性,調(diào)用對象的方法,遍歷整個對象的結(jié)構(gòu)圖,實現(xiàn)字段類型轉(zhuǎn)化等功能。它使用相同的表達式去存取對象的屬性。 XWork遵循“不要重復(fù)地發(fā)明同一個輪子”的理論,它的表達式語言核心用的就是這個OGNL。我們先來看看一個簡單的例子: 還記得我們用戶注冊的那個例子嗎?我們輸入框的name用到的名字就是OGNL的表達式,比如:用戶名的輸入框:“”,在用戶注冊成功之后我們要顯示用戶注冊的信息,用了“ 我們的兩個表達式都是相同的,但前一個保存對象屬性的值,后一個是取得對象屬性的值。表達式語言簡單、易懂卻又功能強大,關(guān)于OGNL更多的介紹可以去http://www.,那里有很詳細的文檔。 值堆棧-OgnlValueStack OGNL在框架中的應(yīng)用,最主要是支持我們的值堆棧(Value Stack)——OgnlValueStack,它主要的功能是通過表達式語言來存取對象的屬性。用戶界面輸入數(shù)據(jù),它會根據(jù)保存表達式將數(shù)據(jù)依次保存到它堆棧的對象中,業(yè)務(wù)操作完成,結(jié)果數(shù)據(jù)會通過表達式被獲取、輸出。 還記得我們用戶注冊的例子嗎?下面我們用一段程序來演示它向OgnlValueStack中保存、取得數(shù)據(jù)的步驟: // DemoRegisterValueStack package example.register;
import com.opensymphony.xwork.util.OgnlValueStack;
/** * @author moxie-qac * achqian@yahoo.com.cn * */ public class DemoRegisterValueStack { public void demo(){ RegisterAction action = new RegisterAction(); OgnlValueStack valueStack= new OgnlValueStack(); valueStack.push(action);
valueStack.setValue("user.username","Moxie"); System.out.println("username = "+valueStack.findValue("user.username")); }
public static void main(String[] args) { DemoRegisterValueStack demoValueStack = new DemoRegisterValueStack(); demoValueStack.demo(); } } 我們來看一看它的demo()方法: 1、創(chuàng)建我們的Action(RegisterAction)類的對象action,將action對象壓入堆棧valueStack中。在WebWrok中Action的創(chuàng)建、入棧是在DefaultActionInvocation構(gòu)造函數(shù)中進行的,詳細介紹見:ServletDispatcher原理。 2、通過表達式語言,調(diào)用堆棧對象的get()、set()方法,設(shè)置該對象的值。 public void setValue(String expr, Object value) 語句:valueStack.setValue("user.username","Moxie"); 的作用等同于:action.getUser().setUsername("Moxie"); 3、通過表達式語言,去堆棧對象中查找我們前面保存的值,并在控制臺打印。valueStack.findValue("user.username")等同與語句: action.getUser().getUsername() 最后控制臺打印的結(jié)果: username = Moxie CompoundRoot 在OgnlValueStack中,一個堆棧其實是一個List。查看OgnlValueStack你會發(fā)現(xiàn),堆棧就是com.opensymphony.xwork.util.CompoundRoot類的對象: public class CompoundRoot extends ArrayList { //~ Constructors ///////////////////////////////////// public CompoundRoot() { } public CompoundRoot(List list) { super(list); } //~ Methods //////////////////////////////////////////// public CompoundRoot cutStack(int index) { return new CompoundRoot(subList(index, size())); } public Object peek() { return get(0); } public Object pop() { return remove(0); } public void push(Object o) { add(0, o); } } 我們通過表達式向堆棧對象操作時,我們并不知道堆棧中有哪些對象。OgnlValueStack會根據(jù)堆棧由上向下的順序(先入棧在下面,最后入棧在最上面)依次去查找與表達式匹配的對象方法,找到即進行相應(yīng)的存取操作。假設(shè)后面對象也有相同的方法,將不會被調(diào)用。 下面我們看一個對OgnlValueStack操作的程序,它主要演示了如何對Map對象的存取和OgnlValueStack堆棧的原理: /* * Created on 2004-6-15 * DemoGroupValueStack.java */ package example.register;
import com.opensymphony.xwork.util.OgnlValueStack;
/** * @author moxie-qac * achqian@yahoo.com.cn * */ public class DemoGroupValueStack {
public void demoAction(){ DemoGroupAction action = new DemoGroupAction(); OgnlValueStack valueStack= new OgnlValueStack(); valueStack.push(action);
User zhao = new User(); zhao.setUsername("zhao"); zhao.setEmail("zhao@yahoo.com.cn");
User qian = new User(); qian.setUsername("qian"); qian.setEmail("qian@yahoo.com.cn");
valueStack.setValue("users[‘zhao‘]",zhao); valueStack.setValue("users[‘qian‘]",qian);
System.out.println("users[‘zhao‘] = "+valueStack.findValue("users[‘zhao‘]")); System.out.println("users[‘qian‘] = "+valueStack.findValue("users[‘qian‘]")); System.out.println("users size = "+valueStack.findValue("users.size"));
System.out.println("allUserName[0] = "+valueStack.findValue("allUserName[0]")); }
public void demoModels(){
User model_a = new User(); model_a.setUsername("model_a"); User model_b = new User(); model_b.setUsername("model_b"); User model_c = new User(); model_c.setUsername("model_c");
OgnlValueStack valueStack= new OgnlValueStack(); valueStack.push(model_a); valueStack.push(model_b); valueStack.push(model_c);
System.out.println("username = "+valueStack.findValue("username")); System.out.println("[1].username = "+valueStack.findValue("[1].username")); System.out.println("[0].toString = "+valueStack.findValue("[0]")); System.out.println("[1].toString = "+valueStack.findValue("[1]")); System.out.println("[2].toString = "+valueStack.findValue("[2]"));
} public static void main(String[] args) { DemoGroupValueStack demoValueStack = new DemoGroupValueStack(); demoValueStack.demoAction(); demoValueStack.demoModels(); } }
/* * Created on 2004-6-15 * DemoAction.java */ package example.register;
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;
/** * @author moxie-qac * achqian@yahoo.com.cn * */ public class DemoGroupAction {
private Map users = new HashMap();
public Map getUsers(){ return this.users; }
public List getAllUserName(){ return new ArrayList(users.keySet()); } public String execute(){ //執(zhí)行業(yè)務(wù)操作 return null; } public String toString(){ return users.toString(); } } 注意:1、Map屬性的存取,它的表達式語言如:users[‘zhao‘],注意它用’’來引用HashMap的key字符串。 2、demoModels()方法演示了OgnlValueStack中堆棧的原理,請?zhí)貏e注意它的[0].toString、[1].toString、[2].toString,它們依次調(diào)用堆棧中對象的toString()方法,并逐一的減少堆棧最上面的對象。 控制臺輸出的結(jié)果如下: users[‘zhao‘] = username=zhao;password=null;email=zhao@yahoo.com.cn;age=0 users[‘qian‘] = username=qian;password=null;email=qian@yahoo.com.cn;age=0 users size = 2 allUserName[0] = qian
username = model_c [1].username = model_b [0].toString = [username=model_c;password=null;email=null;age=0, username=model_b;password=null;email=null;age=0, username=model_a;password=null;email=null;age=0] [1].toString = [username=model_b;password=null;email=null;age=0, username=model_a;password=null;email=null;age=0] [2].toString = [username=model_a;password=null;email=null;age=0] |
|
|
來自: ShangShujie > 《java》