OGNL運算式語言介紹_語言

來源:互聯網
上載者:User

OGNL介紹
OGNL是Object-Graph Navigation Language的縮寫,它是一種功能強大的運算式語言(Expression Language,簡稱為EL),通過它簡單一致的運算式文法,可以存取對象的任意屬性,調用對象的方法,遍曆整個對象的結構圖,實現欄位類型轉化等功能。它使用相同的運算式去存取對象的屬性。
XWork遵循“不要重複地發明同一個輪子”的理論,它的運算式語言核心用的就是這個OGNL。我們先來看看一個簡單的例子:
還記得我們使用者註冊的那個例子嗎。我們輸入框的name用到的名字就是OGNL的運算式,比如:使用者名稱的輸入框:“<input type="text" name="user.username">”,在使用者註冊成功之後我們要顯示使用者註冊的資訊,用了“<ww:property value="user.username"/>”。Input輸入框裡的“user.username”,它解析成Java語句為:getUser().setUsername();,property標籤裡的“user.username”解析為Java語句:getUser.getUsername();。
我們的兩個運算式都是相同的,但前一個儲存對象屬性的值,後一個是取得對象屬性的值。運算式語言簡單、易懂卻又功能強大,關於OGNL更多的介紹可以去http://www.ognl.org,那裡有很詳細的文檔
 
值堆棧-OgnlValueStack
OGNL在架構中的應用,最主要是支援我們的值堆棧(Value Stack)——OgnlValueStack,它主要的功能是通過運算式語言來存取對象的屬性。使用者介面輸入資料,它會根據儲存運算式將資料依次儲存到它堆棧的對象中,業務操作完成,結果資料會通過運算式被擷取、輸出。
還記得我們使用者註冊的例子嗎。下面我們用一段程式來示範它向OgnlValueStack中儲存、取得資料的步驟:
 
// DemoRegisterValueStack
package example.register;
import com.opensymphony.xwork.util.OgnlValueStack;
 
public class DemoRegisterValueStack {
    public void demo(){
        RegisterAction action = new RegisterAction();
        OgnlValueStack valueStack= new OgnlValueStack();
        valueStack.push(action);
       
        valueStack.setValue("user.username","Babydavic");
        System.out.println("username = "+valueStack.findValue("user.username"));
    }
 
    public static void main(String[] args) {
DemoRegisterValueStack demoValueStack = new DemoRegisterValueStack();
        demoValueStack.demo();
    }
}
 
我們來看一看它的demo()方法:
1、   建立我們的Action(RegisterAction)類的對象action,將action對象壓入堆棧valueStack中。在WebWrok中Action的建立、入棧是在DefaultActionInvocation建構函式中進行的,詳細介紹見:ServletDispatcher原理。
2、   通過運算式語言,呼叫堆疊對象的get()、set()方法,設定該對象的值。
   public void setValue(String expr, Object value)
   語句:valueStack.setValue("user.username","Babydavic");
   的作用等同於:action.getUser().setUsername("Babydavic");
3、   通過運算式語言,去堆棧對象中尋找我們前面儲存的值,並在控制台列印。valueStack.findValue("user.username")等同與語句:
action.getUser().getUsername()
最後控制台列印的結果:
         username = Babydavic
 
 
CompoundRoot
在OgnlValueStack中,一個堆棧其實是一個List。查看OgnlValueStack你會發現,堆棧就是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會根據堆棧由上向下的順序(先入棧在下面,最後入棧在最上面)依次去尋找與運算式匹配的對象方法,找到即進行相應的存取操作。假設後面對象也有相同的方法,將不會被調用。
下面我們看一個對OgnlValueStack操作的程式,它主要示範了如何對Map對象的存取和OgnlValueStack堆棧的原理
 
package example.register;
 
import com.opensymphony.xwork.util.OgnlValueStack;
 
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();
    }
}
 
 
package example.register;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
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(){
        //執行業務操作
        return null;
    }
    public String toString(){
        return users.toString();
    }
}
注意:1、Map屬性的存取,它的運算式語言如:users['zhao'],注意它用’’來引用HashMap的key字串。
2、demoModels()方法示範了OgnlValueStack中堆棧的原理,請特別注意它的[0].toString、[1].toString、[2].toString,它們依次呼叫堆疊中對象的toString()方法,並逐一的減少堆棧最上面的對象。
控制台輸出的結果如下:
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]

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.