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