OGNL詳解


A.什么是OGNL?

  全稱叫ObjectGraphic Navigation Language(對象圖導航語言),它是struts2框架里面的第三方語言(即可以再別的地方用,struts2只是拿過來了而已),它可以調用對象中的方法,獲取struts2里值棧的數據,具體優點https://baike.baidu.com/item/OGNL/10365326?fr=aladdin  

B.OGNL的三要素

  表達式:OGNL表達式是功能強大的表達式語言,何解?在ognl中想要執行取值,賦值,調用方法等等操作,你都需要用表達式表示。通過表達式,底層會解析出來你的想要操作。它支持鏈式結構

  根對象:即root對象,可以理解為OGNL的操作對象,表達式規定做什么,而該對象就指定對誰操作。OGNL叫做對象圖導航語言,對象圖就是以任意一個對象作為根,通過OGNL可以訪問到與這個對象相關的其他對象。底層使用list集合做的。

  Context對象:其實就是OGNL的上下文環境。root對象也在OGNL的上下文環境里,底層是一個Map集合。該上下文環境規定了OGNL操作在“哪里進行”,注意訪問context對象時候需要在表達式中加上#。

 

C.OGNL在java環境的運用。

     ---導入OGNL jar包

  ---用法:

  1.OGNL調用對象的方法

  

@Test
    public void demo1() {
        try {
//            創建context對象
            OgnlContext context = new OgnlContext();
//            利用context來獲取root對象
            Object root = context.getRoot();
//            Ognl中的靜態方法getValue(expression, context, root, resultType)可以用來獲取數據
            Object value = Ognl.getValue("'helloworld'.length()", context, root);  //expression就是方法表達式
            System.out.println(value.toString());
        } catch (OgnlException e) {
            e.printStackTrace();
        }
    }

運行結果

   

2.利用ognl訪問類中的靜態方法

    @Test
    public void demo2() {
        try {
//            創建context對象
            OgnlContext context = new OgnlContext();
//            利用context來獲取root對象
            Object root = context.getRoot();
//            Ognl中的靜態方法getValue(expression, context, root, resultType)可以用來獲取數據
            Object value = Ognl.getValue("@java.lang.Math@random()", context, root); //這里注意獲取靜態方法表達式是固定表達: @類名@方法名
            System.out.println(value.toString());
        } catch (OgnlException e) {
            e.printStackTrace();
        }
    }

運行結果

 

 3.獲取root區中的數據

 
         
創建context對象
            OgnlContext context = new OgnlContext();
//注意,這里不能在getValue方法外面初始化獲取root對象,不然導致該root為null,傳進方法里面,由於root在外面已經被定義,方法底層就不會幫助創建賦值,直接報異常,name值根本不會再存
           Object root = context.getRoot();       
           System.out.println(root);
//            向root區域存值,setRoot(Object obj),root就是通過一個對象找到與它關聯的對象,所以只能用來存對象類型
            User user = new User();
            user.setName("張三");
            context.setRoot(user);
//            root的取值不需要加上#,它是ognl內部的,所以不需要加#來特意告訴ognl
            String value;
            try {
                value = (String) Ognl.getValue("name", context, context.getRoot());
                System.out.println(value);
            } catch (OgnlException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
 
         

 

 

 運行結果

 

4.獲取context區域的值

@Test
    public void demo4() {
//            創建context對象
            OgnlContext context = new OgnlContext();
//            利用context來獲取root對象
            Object root = context.getRoot();
//            向context區域存值,set一般向里面存對象,而context區域用put是存值
            context.put("name","張薩姆");
            String value;
            try {
//            root的取值不需要加上#,它是ognl內部的,所以不需要加#來特意告訴ognl,而context區域上該ognl的所處的上下文環境,外部,要加上#說明
                value = (String) Ognl.getValue("#name", context, root);
                System.out.println(value);
            } catch (OgnlException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
    }

運行結果

 

D.ognl在struts2環境的介紹

   如果是jsp頁面,需要先引入ognl標簽庫才能用

  <%@ taglib uri="/struts-tags" prefix="s" %>

1.訪問對象中的方法

  

<h3>訪問對象中的方法</h3>
<s:property value="'helloworld'.substring(5)"/>    //剪切字符串

  運行結果

2.訪問靜態方法

  注意:struts2中默認靜態訪問方法是關閉的,怎么查看了,打開library---->/org/apache/struts2---->default.properties.所以我們需要手動在struts.xml文件里面開啟它,才能實現靜態訪問

 

  <struts>
    <!-- 開啟靜態方法訪問常量 -->
    <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

    <package name="struts" extends="struts-default"></package>
  </struts>

運行結果:

 

 

后面獲取root還有context區域的值就涉及到了值棧的知識了,后面繼續,還涉及到了在值棧存值的知識。當然在jsp中獲取contex和root存值,也可以在jsp中利用ognl表達式取值,但是用action比較正規一點。先大致看一下,什么都不存時候context區域

<h3>訪問context區域</h3>
<s:property value="#session"/>
<s:debug/>

運行結果

 

 看到了吧,取到了session,但是session里面什么樣子,拿到就有哪些值,所以后面值棧繼續。

好了,就講到這里。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM