Struts2【OGNL、valueStack】就是這麼簡單
什麼是OGNL表示式?
OGNL是Object Graphic Navigation Language 是操作物件屬性的開源表示式。 Struts2框架使用OGNL作為預設的表示式語言。
為什麼我們學習OGNL
在學習JSP的時候,我們已經學習過了EL表示式。EL表示式用起來也十分簡單…我們在Struts2框架中也是可以使用EL表示式的…那麼OGNL表示式好在哪裡呢??
- 支援物件方法呼叫,如xxx.doSomeSpecial()
- 支援類靜態的方法呼叫和值訪問,表示式的格式【例如:”@@floor(10.9)”就是呼叫Math.floor()的方法了】
- 支援賦值操作和表示式串聯【這個其實EL表示式也能做】
- 訪問OGNL上下文(OGNL context)和ActionContext
- 操作集合物件【EL只能遍歷集合,OGNL可以建立集合】
OGNL是Struts2的預設表示式語言,OGNL是配搭Strut2的標籤使用的..我們學習了OGNL表示式,就可以更好地理解Struts2標籤的執行以及Struts2內部的儲存結構.
valueStack物件
在講解OGNL表示式之前,我們先來看看valueStack物件…valueStack是Struts2資料儲存的核心…我們首先要知道資料是怎麼存的,存到哪裡,然後才講解OGNL表示式是怎麼取出資料的。
valueStack也被稱作值棧物件..
- 當用戶訪問Action,都會建立一個Action物件,ActionContext物件、valueStack物件..
- Struts2把Action物件放進valueStack物件之中。
- 將valueStack放進request域中,傳入JSP頁面(key: struts.valueStack)
- JSP頁面就可以使用OGNL表示式獲取值棧中的資料了!
獲取valueStack物件
- 在Action中我們可以手動獲取值棧物件,有兩種方式獲取:
//獲取值棧物件的2種方式
private void getVs() {
// 獲取值棧物件,方式1:
HttpServletRequest request = ServletActionContext.getRequest();
ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack" );
// 獲取值棧物件,方式2:
ActionContext ac = ActionContext.getContext();
ValueStack vs2 = ac.getValueStack();
System.out.println(vs1 == vs2);//true
}
valueStack內部儲存結構
上面已經說了,使用者訪問Action時,會建立Action物件,valueStack物件。Struts2內部會將Action物件存到valueStack物件之中…那麼valueStack的儲存結構是什麼樣的呢???我們來看看
CompoundRoot
Action物件和Action的成員屬性等值都是存到CompoundRoot下的.該CompoundRoot繼承著ArrayList,因此它是List結構的
public class CompoundRoot extends ArrayList {}
OgnlContext
OgnlContext物件儲存著相關的域物件:request、response、session等資料,實現Map集合,是Map結構..
為了讓request、response等域物件可以儲存多個值,值也是使用Map結構…
public class OgnlContext implements Map {}
小總結
CompoundRoot儲存著這樣的資料:
- Action物件以及Action物件的成員屬性資料
- 使用ValueStack物件.push()進去的資料
- 使用ValueStack物件.set()進去的資料
- 其他代理物件的資料
OgnlContext儲存著這樣的資料:
- 維護了CompoundRoot中所有的資料
- request、response等域物件所有的資料
OGNL表示式取值
- Struts2會將valueStack物件封裝進request物件域中,傳入JSP頁面。
- valueStack儲存著OgnlContext物件。
- OgnlContext物件維護了CompoundRoot物件的資料
- CompoundRoot儲存著Action等資料
也就是說通過OgnlContext物件可以獲取大部分我們需要的資料了。
那麼OGNL表示式是怎麼取出OgnlContext物件中資料的呢??下面我們通過硬編碼的方式來講解:
/**
* 1. Ognl表示式語言語言取值,取非根元素的值,必須用#號
* @throws Exception
*/
@Test
public void testOgnl() throws Exception {
// 建立一個Ognl上下文物件
OgnlContext context = new OgnlContext();
// 放入資料
User user = new User();
user.setId(100);
user.setName("Jack");
// 【往非根元素放入資料, 取值的時候表示式要用"#"】
context.put("user", user);
// 獲取資料(map)
// 先構建一個Ognl表示式, 再解析表示式
Object ognl = Ognl.parseExpression("#user.name");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
/**
* 2. Ognl表示式語言語言取值,取根元素的值,不用帶#號
* @throws Exception
*/
@Test
public void testOgn2() throws Exception {
// 建立一個Ognl上下文物件
OgnlContext context = new OgnlContext();
// 放入資料
User user = new User();
user.setId(100);
user.setName("Jack");
// 【往根元素放入資料】
context.setRoot(user);
// 獲取資料(map)
// 先構建一個Ognl表示式, 再解析表示式
Object ognl = Ognl.parseExpression("address.province");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
也就是說,JSP頁面中取出資料的時候,它會先構建一個OGNL表示式,再解析表示式
- 如果是CompoundRoot類的資料,表示式不需要帶#號
- 如果不是CompoundRoot類的資料,表示式需要帶#號
例子:
<!-- 頁面: 必須要拿到ValueStack -->
<br/>1. 取根元素的值<br/>
<s:property value="user.id"/>
<s:property value="user.name"/>
<s:property value="user.address"/>
<s:property value="user.address.city"/>
<s:property value="user.address.province"/>
<br/>2. 取非根元素的值<br/>
<s:property value="#request.cn"/>
<s:property value="#session.Session_data"/>
<s:property value="#application.Application_data"/> <br/>
<!-- 自動找request/session/application,找到後立刻返回 -->
<s:property value="#request_data"/>
<s:property value="#attr.Session_data"/>
<s:property value="#attr.Application_data"/> <br/>
<!-- 獲取請求的引數資料 -->
<s:property value="#parameters.userName"/>
<!-- struts的除錯標籤:可以觀測值棧資料 -->
<s:debug></s:debug>
OGNL對靜態方法的呼叫
/**
* 3.Ognl對 靜態方法呼叫的支援
* @throws Exception
*/
@Test
public void testOgn3() throws Exception {
// 建立一個Ognl上下文物件
OgnlContext context = new OgnlContext();
// Ognl表單式語言,呼叫類的靜態方法
//Object ognl = Ognl.parseExpression("@[email protected](10.9)");
// 由於Math類在開發中比較常用,所以也可以這樣寫
Object ognl = Ognl.parseExpression("@@floor(10.9)");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
OGNL建立集合
<br/>一、.構建 list集合</br>
<s:iterator var="str" value="{'a','b'}">
<s:property value="#str"/>
</s:iterator>
<br/>一、.構建 map集合</br>
<s:iterator var="en" value="#{'cn':'China','usa':'America'}">
<s:property value="#en.key"/>
<s:property value="#en.value"/> <br/>
</s:iterator>
構建Map集合的時候,需要使用#號
OGNL 幾個特殊的符號
#獲取非根元素值 、 動態都建map集合
$ 在配置檔案取值
% 提供一個ognl表示式執行環境
<body>
<br/>獲取request域資料<br/>
<!-- property 標籤是物件型別的標籤,預設支援ognl表示式, 會從根元素去China名稱對應的值 -->
<s:property value="China"/> <br/>
<!-- 如果直接賦值,需要用單引號 -->
<s:property value="'China'"/> <br/>
<s:property value="%{#request.cn}"/> <br/>
<!-- 值型別的標籤,value值預設就是值型別,不支援ognl表示式 -->
國家:<s:textfield name="txtCountry" value="%{#request.cn}"></s:textfield>
</body>
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y
相關推薦
Struts2【OGNL、valueStack】就是這麼簡單
什麼是OGNL表示式? OGNL是Object Graphic Navigation Language 是操作物件屬性的開源表示式。 Struts2框架使用OGNL作為預設的表示式語言。 為什麼我們學習OGNL 在學習JSP的時候,我們已經學習過了EL
【JavaEE筆記】Struts2 (三) ognl、值棧操作等
一. ognl概述 1. 在web階段,學習過EL表示式,EL表示式在JSP中獲取域物件裡面的值 2. ognl是一種表示式,這個表示式功能更加強大 i.在struts2裡面操作值棧資料 ii.
【教程】一鍵挖礦就這麼簡單-ITGC
最近有很多朋友請教我如何挖礦,而挖礦這個事,三言兩語又很難說清楚,目前主流幣過高的挖礦投入、技術門檻都讓小白們“望幣興嘆”。對於新朋友而言,再生派(ITGC)是一個很好的切入點。 再生派(貨幣代號ITGC),一個基於區塊鏈的跨平臺、多落地應用的資源再流通生
【BZOJ3781、2038】莫隊算法2水題
bsp space har 情況 ros clu while 給定 print 【BZOJ3781】小B的詢問 題意:有一個序列,包含N個1~K之間的整數。他一共有M個詢問,每個詢問給定一個區間[L..R],求Sigma(c(i)^2)的值,其中i的值從1到K,其中c(i
python16_day17【Django_session、ajax】
cookies span ajax 失效 lte obj code keys def 一、Session 1.settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ # 引擎(默認)
字節輸入流寫文本文件【OutputStream、FileOutputStream】
byte[] 方法名 cell end borde 方法 oid 所有 寫入文件 字節輸入流寫文本文件 1.OutputStream基類 作用:把內存中的數據輸出到文件中。 ※OutputStream類的常用方法 方法名稱 說明
001-docker安裝【nginx、mysql】
瀏覽器 配置 操作 nbsp emctl mct lac 這就是 systemctl 一、 1、系統配置要求 操作系統:64位操作系統和3.10或者更高版本的內核:uname -r Docker-v1.12 及更高版本 Docker Compose-v1
MySQL開發——【介紹、安裝】
dbms tab 數據結構 個數 關系模型 集合 base 存儲 模型 什麽是數據庫? 數據庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫, 每個數據庫都有一個或多個不同的API用於創建,訪問,管理,搜索和復制所保存的數據。 數據庫的分類?
智能家居入門DIY——【四、組合】
vat -- cond 一點 ros 但是 comm end 上電 前面幾篇介紹了一些傳感器和代碼,這篇介紹一下把它們組合起來。之所以單獨列出這部分,原因在於組合更多功能的時候發現使用軟串口庫驅動ESP8266時由於內存過小導致發送失敗甚至整個系統無法工作的
EFCore 【Sqlite、Mysql】資料庫遷移 並使用資料庫,CodeFirst、DBFirst
通過alt+v+e+o組合鍵來喚醒程式包管理器 通過在程式包管理器控制檯中輸入指令: get-help about_entityframeworkcore 檢視EFCore的幫助文件。 EFCore CodeFirst EFCore 使用Sqlite資料庫遷移的步驟: 第一步
JavaScript_12設計模式(單體模式【五、六】)惰性單體和分支單體
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>New Web Project</title>
Java第一階段(12)【 異常、集合 】 11.21
第一階段 異常 集合 練習 異常 異常大家族 Throwable 錯誤 :Error ,不能處理的,只能去修改程式碼 異常 :Exception, 可以處理,程式碼不用改,使用異常處理的方案來繞過異常
nginx + tomcat 8.5 優化配置,安裝nginx【centos6、7】
第一步安裝 軟體 1.1 依賴包 # yum -y install gcc # yum install expat-devel # sudo yum install zlib-devel 到http://apr.apache.org/download.cgi#apr1這
STL原始碼剖析(五)【hash_set、hash_map】
hash_set 與set區別及聯絡 與set大同小異,set以RB-tree作為其底層,而hash_set以hash table作為其底層 兩者都是藉由其底層操作完成我們所看到的那些操作 二者最大的不同在於set的底層RB-tree有自動排序功能,所以反映在se
三、亞馬遜產品定價其實就這麼簡單,一個公式解決
目錄 海貓跨境作者:海貓跨境 2016-11-24 16:33:51 如果產品銷量不好,很多賣家首先想到的是圖片、listing是不是做的不夠好,很少賣家會想想是不是自己的定價有問題,定價對銷量的影響也是至關重要的,定價是一門高深的學問,如果產品
【NOJ1596、1597】【貪心演算法之最小生成樹】最少修建多長的公路能把所有村莊連起來(圖示Prim與Kruskal演算法)
1596.最少修建多長的公路能把所有村莊連起來(一) 時限:1000ms 記憶體限制:10000K 總時限:3000ms 描述 一個地區有n個村莊,有一些村子之間可以修路,已知每條路的長度,問最少修建多長的公路可以把所有的村子連線起來。 輸入 先輸入兩個正整數n,
一次心驚肉跳的伺服器誤刪檔案的恢復過程【轉載、收藏】 一次心驚肉跳的伺服器誤刪檔案的恢復過程
一次心驚肉跳的伺服器誤刪檔案的恢復過程 經歷了兩天不懈努力,終於恢復了一次誤操作刪除的生產伺服器資料。對本次事故過程和解決辦法記錄在此,警醒自己,也提示別人莫犯此錯。也希望遇到問題的朋友能找到一絲靈感解決問題。 事故背景 安排一個妹子在一臺生產伺服器上安裝Oracle,妹子
4、《SSO CAS單點系列》之 實操!輕鬆玩轉SSO CAS就這麼簡單(相遇篇)
CAS是中央認證服務Central Authentication Service的簡稱。最初由耶魯大學的Shawn Bayern 開發,後由Jasig社群維護,經過十多年發展,目前已成為影響最大、廣泛使用的、基於Java實現的、開源SSO解決方案。2012年,Jasig和另一
CentOS7下三步安裝單點OpenStack【KVM、VMwareOK】
失敗7次後成功。 注意:1、必須CENTOS7,主要是python要2.7,yum要能用 2、關閉NetworkManager 3、多次安裝,千萬別修改IP,否則,必然失敗 4、安裝過程中,失敗多次,處理各不同:【不知道是否與我的網路情況有關,導致失敗多次】 使用配置參
jetbrains系列啟用\註冊碼\破解碼【Webstorm、DataGrip】
【有效】https://s.tuzhihao.com:666/【失效】http://hb5.s.osidea.cc:1017【有效】codeK03CHKJCFT-eyJsaWNlbnNlSWQiOiJLMDNDSEtKQ0ZUIiwibGljZW5zZWVOYW1lIjoib