1. 程式人生 > 實用技巧 >JavaWeb學習:OGNL

JavaWeb學習:OGNL

一、OGNL:Object-Graph Navigation Language(物件導航圖語言)的縮寫,是應用於Java中的一個開源的表示式語言

二、OGNL的優勢:

  • 支援物件方法呼叫
  • 支援靜態方法呼叫和值訪問(表示式:@[類全名(包括包路徑)]@[方法名 | 值名])
  • 支援賦值操作和表示式串聯
  • 訪問OGNL上下文
  • 操作集合
  • 可以new 一個物件

三、Java環境

  ①、物件方法呼叫

  @Test
    public void demo1() throws OgnlException {
    OgnlContext context = new OgnlContext();
    Object root 
= context.getRoot(); Object object = Ognl.getValue("'hellow ognl'.length()", context, root); System.out.println(object); }

  ②、靜態方法呼叫和值訪問

   @Test
    public void demo2() throws OgnlException {
    OgnlContext context = new OgnlContext();
    Object root = context.getRoot();
    Object object 
= Ognl.getValue("@java.lang.Math@random()", context, root); System.out.println(object); }

  ③、賦值操作和表示式串聯

  @Test
    public void demo3() throws OgnlException {
    OgnlContext context = new OgnlContext();
    Object root = context.getRoot();
    Object object = Ognl.getValue("price=100, discount=0.8, price*discount", context, root);
    System.out.println(object);
    }

    出現異常:ognl.OgnlException: target is null for setProperty(null, "price", 100),不知道怎麼解決

  ④、訪問OGNL上下文(OgnlContext)

    

public class User {
    private String userName;
    private String passWord;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassWord() {
        return passWord;
    }
    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
    public User(String userName, String passWord) {
    this.userName = userName;
    this.passWord = passWord;
    }
    public User() {
    }
    
}

    4.1、訪問Root中的資料

    @Test
    public void demo4() throws OgnlException {
    OgnlContext context = new OgnlContext();
    context.setRoot(new User("zhangsan","123"));
    Object root = context.getRoot();
    Object username = Ognl.getValue("userName", context, root);
    Object password = Ognl.getValue("passWord", context, root);
    System.out.println(username+":"+password);
    }

    4.2、訪問context中的資料,需要加#

    @Test
    public void demo5() throws OgnlException {
    OgnlContext context = new OgnlContext();
    Object root = context.getRoot();

    context.put("name", "zhangsan");
    Object name=Ognl.getValue("#name", context, root);
    System.out.println(name);
    }

四、Struts2環境

  ①、物件方法呼叫、靜態方法呼叫

<!-- 呼叫物件方法 -->
<s:property value="'hello struts ognl'.length()"/>
<!-- 
在struts2中靜態方法訪問預設式禁止訪問的,
需要設定一個常量(struts.ognl.allowStaticMethodAccess=true)開啟訪問許可權 
-->
<s:property value="@java.lang.Math@random()"/>
<!-- 賦值操作和表示式串聯(無法正常顯示,不知道為什麼)  -->
<s:property value="price=100, discount=0.8, price*discount"/>

  ②、訪問ognl上下文(OgnlContext)需要使用ValueStack儲存資料

    2.1、在Struts2環境中使用OGNL語法,主要作用:資料庫傳輸(Struts2的框架中的資料都儲存到ValueStack中)

      • ValueStack介面,實現類OgnlValueStack物件
      • ValueStack貫穿整個Action的生命週期

2.2、ValueStack中有兩個主要區域:

   root:其實就是一個ArrayList,主要儲存物件

   context:其實就是一個Map,主要儲存web開發常用物件資料庫的引用

    

      操作值棧是指操作ValueStack的root區域,而操作request、session、application、就相當於操作context區域

          可以通過Debug方式檢視,具體程式碼

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h3>Success</h3>
    <s:debug></s:debug>
</body>
</html>

          root區域的內容

            

          context區域

            

    2.3、值棧與ActionContext的關係

      ActionContext:Action的上下文,當有請求時,執行過濾器中的doFilter方法,此方法會建立ActionContext,在建立ActionContext過程中建立ValueStack物件,並將ValueStack物件儲存在ActionContext中,所以可以通過ActionContext獲取值棧物件(ActionContext.getContext().getValueStack()

        ActionContext物件可以訪問Servlet的API(訪問的是域物件的資料),因為其內部有值棧的引用。

    2.4、ValueStack的獲取

      1、通過ActionContext物件獲取值棧(ActionContext.getContext().getValueStack())

      2、在Struts2內部將值棧存入request物件中(ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY)