1. 程式人生 > >ssh框架Struts2 OGNL和框架值棧

ssh框架Struts2 OGNL和框架值棧

主要內容

1. OGNL表示式(瞭解)
2. Struts2框架的值棧(值棧、存入值、取值)
3. OGNL的特殊符號

OGNL表示式概述

1. OGNL是Object Graphic Navigation Language(物件圖導航語言)的縮寫
    * 所謂物件圖,即以任意一個物件為根,通過OGNL可以訪問與這個物件關聯的其它物件
    * 通過它簡單一致的表示式語法,可以存取物件的任意屬性,呼叫物件的方法,遍歷整個物件的結構圖,實現欄位型別轉化等功能。它使用相同的表示式去存取物件的屬性

2. Struts2框架使用OGNL作為預設的表示式語言
    * OGNL是一種比EL強大很多倍的語言
    * xwork提供 OGNL表示式
    * ognl-3.0.5.jar

3. OGNL 提供五大類功能
   * 支援物件方法呼叫
   * 支援類靜態的方法呼叫和值訪問
   * 訪問OGNL上下文(OGNL context)和ActionContext
   * 支援賦值操作和表示式串聯
   * 操作集合物件

4. 測試的程式碼
    // 訪問物件的方法
    @Test
    public void run1() throws OgnlException{
        OgnlContext context = new OgnlContext();
        // 獲取物件的方法
        Object obj = Ognl.getValue("'helloworld'.length()", context, context.getRoot());
        System.out.println(obj);
    }

    // 獲取OGNL上下檔案的物件
    @Test
    public void run3() throws OgnlException{
        OgnlContext context = new OgnlContext();
        context.put("name", "美美");
        // 獲取物件的方法
        Object obj = Ognl.getValue("#name", context, context.getRoot());
        System.out.println(obj);
    }

    // 從root棧獲取值
    @Test
    public void demo3() throws OgnlException{
        OgnlContext context = new OgnlContext();
        Customer c = new Customer();
        c.setCust_name("haha");
        context.setRoot(c);
        String name = (String) Ognl.getValue("cust_name", context, context.getRoot());
        System.out.println(name);
    }

Struts2框架中使用OGNL表示式

1. Struts2引入了OGNL表示式,主要是在JSP頁面中獲取值棧中的值
2. 具體在Struts2中怎麼使用呢?如下步驟
    * 需要先引入Struts2的標籤庫
        > <%@ taglib prefix="s" uri="/struts-tags" %>

    * 使用Struts2提供的標籤中的標籤
        > <s:property value="OGNL表示式"/>

3. 在JSP頁面使用OGNL表示式
    * 訪問物件方法
        <s:property value="'hello'.length()"/>

值棧的概述

1. 問題一:什麼是值棧?
    * 值棧就相當於Struts2框架的資料的中轉站,向值棧存入一些資料。從值棧中獲取到資料。
    * ValueStack 是 struts2 提供一個介面,實現類 OgnlValueStack ---- 值棧物件 (OGNL是從值棧中獲取資料的 )
    * Action是多例的,有一起請求,建立Action例項,建立一個ActionContext物件,代表的是Action的上下文物件,還會建立一個ValueStack物件。
    * 每個Action例項都有一個ValueStack物件 (一個請求 對應 一個ValueStack物件 )
    * 在其中儲存當前Action 物件和其他相關物件
    * Struts 框架把 ValueStack 物件儲存在名為 “struts.valueStack” 的請求屬性中,request中 (值棧物件 是 request一個屬性)
        * ValueStack vs = (ValueStack)request.getAttribute("struts.valueStack");

值棧的內部結構

2. 問題二 : 值棧的內部結構 ?
    * 值棧由兩部分組成
        > root      -- Struts把動作和相關物件壓入 ObjectStack 中--List
        > context   -- Struts把各種各樣的對映關係(一些 Map 型別的物件) 壓入 ContextMap 中

    * Struts會預設把下面這些對映壓入ContextMap(context)中
        * 注意:request代表的是Map集合的key值,value的值其實也是一個Map集合。

        > parameters: 該 Map 中包含當前請求的請求引數  ?name=xxx&password=123
        > request: 該 Map 中包含當前 request 物件中的所有屬性
        > session: 該 Map 中包含當前 session 物件中的所有屬性
        > application:該 Map 中包含當前 application  物件中的所有屬性
        > attr: 該 Map 按如下順序來檢索某個屬性: request, session, application

    * ValueStack中 存在root屬性 (CompoundRoot) 、 context 屬性 (OgnlContext )
        > CompoundRoot 就是ArrayList
        > OgnlContext 就是 Map

    * context 對應Map 引入 root物件 
        > context中還存在 request、 session、application、 attr、 parameters 物件引用 
        > OGNL表示式訪問值棧中的資料
            * 訪問root中資料時 不需要 #
            * 訪問 request、 session、application、 attr、 parameters 物件資料 必須寫 # 

        > 操作值棧 預設指 操作 root 元素

值棧的建立和ActionContext物件的關係

3. 問題三 : 值棧物件的建立,ValueStack 和 ActionContext 是什麼關係?
    * 值棧物件是請求時建立的
    * ActionContext是繫結到當前的執行緒上,那麼在每個攔截器或者Action中獲取到的ActionContext是同一個。
    * ActionContext中存在一個Map集合,該Map集合和ValueStack的context是同一個地址。
    * ActionContext中可以獲取到ValueStack的引用,以後再開發,使用ActionContext來獲取到值棧物件

獲取到值棧的物件

4. 問題四 : 如何獲得值棧物件
    * 獲得值棧物件 有三種方法
        * ValueStack vs1 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
        * ValueStack vs2 = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
        * ValueStack vs3 = ActionContext.getContext().getValueStack();

向值棧中儲存資料

5. 問題五: 向值棧儲存資料 (主要針對root棧)
    > valueStack.push(Object obj);
        * push方法的底層呼叫root物件的push方法(把元素新增到0位置)

    > valueStack.set(String key, Object obj);
        * 原始碼獲取map集合(map有可能是已經存在的,有可能是新建立的),把map集合push到棧頂,再把資料存入到map集合中。

    > 在jsp中 通過 <s:debug /> 檢視值棧的內容

從值棧中獲取值

6. 問題六: 在JSP中獲取值棧的資料
    * 總結幾個小問題:
        > 訪問root中資料 不需要#
        > 訪問context其它物件資料 加 #
        > 如果向root中存入物件的話,優先使用push方法。
        > 如果向root中存入集合的話,優先要使用set方法。

    * 在OgnlContext中獲取資料
        > 在Action中向域物件中存入值
        > request:<s:property value="#request.username"/>
        > session:<s:property value="#session.username"/>
        > application:<s:property value="#application.username"/>
        > attr:<s:property value="#attr.username"/>
        > parameters:<s:property value="#parameters.cid"/>

6.1 程式碼如下
    <!--
        // vs.push("美美");
        // 獲取到棧頂的值
        <s:property value="[0].top"/>
    -->

    <!--
        // 棧頂是map集合,通過key獲取值
        vs.set("msg", "小鳳");
        <s:property value="[0].top.msg"/>
    -->

    <!--  
        vs.push(user);
        // 棧頂放user物件
        <s:property value="[0].top.username"/>
        <s:property value="[0].top.password"/>
        // [0].top 關鍵字是可以省略的  findValue()
        <s:property value="username"/>
    -->

    <!--
        vs.set("user", user);
        <s:property value="[0].top.user.username"/>
        <s:property value="[0].top.user.password"/>
        // 省略關鍵字
        <s:property value="user.username"/>
    -->

    <!--  
        // 在ValueStack1Action提供了成員的屬性
        private User user = new User("小澤","456");
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }

        User user = new User("小蒼","123");
        vs.set("user", user);
        // 從棧頂開始查詢,找user的屬性,顯示名稱    返回的小蒼
        <s:property value="user.username"/>

        // [1].top獲取ValueStack1Action [1].top.user返回user物件  [1].top.user.username獲取物件的屬性名稱
        <s:property value="[1].top.user.username"/>
    -->

    <!--  
        棧頂是list集合
        vs.push(ulist);
        <s:property value="[0].top[0].username"/>
        <s:property value="[0].top[1].username"/>
    -->

    <!--
        vs.set("ulist", ulist);
        <s:property value="ulist[0].username"/>
    -->

    <!-- 迭代的標籤 
        屬性
            * value 要迭代的集合,需要從值棧中獲取
            * var   迭代過程中,遍歷的物件
                * var編寫上,把迭代產生的物件預設壓入到context棧中,從context棧取值,加#號
                * var不編寫,預設把迭代產生的物件壓入到root棧中

        for(User user:ulist){}  
        // 編寫var的屬性
        <s:iterator value="ulist" var="u">
            <s:property value="#u.username"/>
            <s:property value="#u.password"/>
        </s:iterator>

        // 沒有編寫var關鍵字
        <s:iterator value="ulist">
            <s:property value="username"/>
            <s:property value="password"/>
        </s:iterator>
    -->

    <!-- 從context棧中獲取值,加#號

    HttpServletRequest request = ServletActionContext.getRequest();
    request.setAttribute("msg", "美美");
    request.getSession().setAttribute("msg", "小風");

    <s:property value="#request.msg"/>
    <s:property value="#session.msg"/>
    <s:property value="#parameters.id"/>
    <s:property value="#attr.msg"/>
    -->

    <!-- 在JSP頁面上,檢視值棧的內部結構 -->
    <s:debug></s:debug>

EL表示式也會獲取到值棧中的資料

7. 問題七:為什麼EL也能訪問值棧中的資料?
    * StrutsPreparedAndExecuteFilter的doFilter程式碼中 request = prepare.wrapRequest(request);    
        > 對Request物件進行了包裝 ,StrutsRequestWrapper
        > 增強了request的 getAttribute
            Object attribute = super.getAttribute(s);
            if (attribute == null) {
               attribute = stack.findValue(s);
            }
        > 訪問request範圍的資料時,如果資料找不到,去值棧中找 
        > request物件 具備訪問值棧資料的能力 (查詢root的資料)

總結OGNL表示式的特殊的符號

1. # 符號的用法
    * 獲得contextMap中的資料
        > <s:property value="#request.name"/>
        > <s:property value="#session.name"/>
        > <s:property value="#application.name"/>
        > <s:property value="#attr.name"/>
        > <s:property value="#parameters.id"/>
        > <s:property value="#parameters.name"/>

    * 構建一個map集合
        * 例如:
            * <s:radio name="sex" list="{'男','女'}"></s:radio>
            * <s:radio name="sex" list="#{'0':'男','1':'女'}"></s:radio>

2. % 符號的用法
    * 強制字串解析成OGNL表示式。
        > 例如:在request域中存入值,然後在文字框(<s:textfield>)中取值,現在到value上。
        > <s:textfield value="%{#request.msg}"/>

    * { }中值用''引起來,此時不再是ognl表示式,而是普通的字串
        > 例如:<s:property value="%{'#request.msg'}"/>

3. $ 符號的用法
    * 在配置檔案中可以使用OGNL表示式,例如:檔案下載的配置檔案。
        <action name="download1" class="cn.itcast.demo2.DownloadAction">
            <result name="success" type="stream">
                <param name="contentType">${contentType}</param>
                <param name="contentDisposition">attachment;filename=${downFilename}</param>
            </result>
        </action>

相關推薦

ssh框架Struts2 OGNL框架

主要內容 1. OGNL表示式(瞭解) 2. Struts2框架的值棧(值棧、存入值、取值) 3. OGNL的特殊符號 OGNL表示式概述 1. OGNL是Object Graphic Navigation Language(物件圖導航語言)的縮寫

struts2學習三(OGNLValueStack

1、OGNL OGNL(Object-Graph Navigation Language),它是一種功能強大的表示式語言,比EL更強大的表示式語言(開源)。struts整合OGNL表示式。使用OGNL作為預設的表示式語言。 主要功能: 1、存取物件的屬性,

Struts2(三)】OGNL表示式與

1.2 相關知識點 1.2.1 什麼是OGNL OGNL:物件圖導航語言,比EL表示式強大很多倍的語言。       EL:從域物件中獲取資料,從EL的11個物件中獲取。${name}${pageContextPath}   &nbs

Struts2OGNL表示式與

1、概述:OGNL的全稱是Object Graph Navigation Language(物件圖導航語言),它是一種強大的表示式語言,Struts框架使用OGNL作為預設的表示式語言。 2、OGNL 有一個上下文(Context)概念,它是一個map結構,因為它實現了java.utils.Ma

struts框架問題五之向中儲存資料

5. 問題五: 向值棧儲存資料 (主要針對root棧) > valueStack.push(Object obj); * push方法的底層呼叫root物件的push方法(把元素新增到0位置) > valueStack.set(String key, Object

struts框架問題六之從中獲取

  6. 問題六: 在JSP中獲取值棧的資料 * 總結幾個小問題: > 訪問root中資料 不需要# > 訪問context其它物件資料 加 # > 如果向root中存入物件的話,優先使用push方法。 > 如果向

Struts2學習(四)———— ognl表示式、、actionContext之間的關係

一、什麼是Ognl?       通過百度百科查詢到的解釋,其中詳細的說明了OGNL的作用。                  下面我們就對OGNL這5個作用進行講解       1、存取物件的任意屬性,簡單說就是對javabean進行操作(重要)       2、呼叫物件方法。       3、

關於struts2中直接操作作用域操作的對比以及的理解

 注:參考文章:https://www.cnblogs.com/bamaw/p/7259232.html 自從初學struts2框架以來,時常和值棧打交道。值棧究竟是什麼,對於我們使用者來說值棧是一個非常方便的東西,很形象的可以稱其為“資料中轉站”。為什麼會有這種叫法呢,因為

Struts2學習總結(3)--Ognl表示式,Struts標籤庫,國際化,資料校驗,攔截器

本文包括以下五個部分: 值棧。Ognl表示式。struts2標籤庫。國際化。表單資料校驗攔截器。struts2的執行過程。一、值棧 採用servlet和JSP開發時,servlet通過域物件儲存資料,在JSP頁面通過jstl標籤+el表示式獲取資料。 採用struts2和

struts2 ognl的傳原理

OGNL 1.1 OGNL的全稱是Object Graph Navigation Language(物件圖導航語言),它是一種強大的表示式語言 1.2 OgnlContext(ongl上下文)其實就是Map (教室、老師、學生) OgnlContext=根物件(1)+非根物件(N)

day33Struts2Day03(OGNL表示式、)

回顧 1、Servlet的API ActionContext物件 ServletActionContext物件 2、結構型別的跳轉 全域性結果 區域性結構 type屬性 3、資料的封裝 屬性驅動方式 模型驅動方式 實現ModelDrivern 介面 4

OGNL表示式取中的

首先,簡單介紹一下Struts2標籤 使用Struts2標籤,需要先在頁面中引入Struts2標籤庫: <%@ taglib prefix="s" uri="/struts-tags" %>標籤庫的位置在struts2-core-2.3.1.2.jar包中的M

struts2異常處理機制-----作用

<struts>    <package name="default">        ...        <global-results>            <result name="login"type="redirect">/Login.actio

[struts2.x] 探索struts如何賦給action成員變數

接著上篇部落格論述: 測試到這裡,我要的結果已經有了,但是我還有個疑問,就是我並沒有指定map的實現類,struts2.x是用什麼策略去例項化這個map的?為了探索這個問題,我做了如下測試,這個測試的內容比上述還有意義得多O(∩_∩)O~。 首先,還是不指定map的實現類,

Struts2筆記10 向放入或獲取資料

1.向值棧放資料多種方式 (1)獲取值棧物件,呼叫值棧物件裡面的set方法 (2)獲取值棧物件,呼叫值棧物件裡面的push方法 (3)在action定義變數,生成變數的get方法

框架 day29 Struts2-上傳,下載,OGNLStruts2的結合(與ActionContext),Struts2標籤,Token機制

檔案上傳 1.1回顧 *瀏覽器端:        <form    method="post"     enctyp="multipart/form-data">               <input   type="file" name="imag

【基於初學者的SSHstruts2 的詳解與struts2標簽庫+ognl表達式

radi ring etl action 值棧 多選 https submit 技術分享 一:什麽是值棧:struts2裏面本身提供的一種存儲機制,類似於域對象,值棧,可以存值和取值  特點:先進後出,最上面的元素叫做棧頂,也叫壓棧。  <s:debug><

SSH框架的搭建測試(Spring + Struts2 + Hibernate)

conf work fault 項目 -i extends struts2 scrip map SSH框架實現了視圖、控制器、和模型的徹底分離,同時還實現了業務邏輯層與持久層的分離。 Spring實現了MVC中的 Controller的功能,Struts實現Web視圖的功能

Struts2第三天:Struts2OGNL表示式

目錄 1.OGNL 1.1OGNL概述 1.1.1什麼是OCNL 1.1.2為什麼學習OGNL 1.1.3OGNL使用的要素 1.2OGNL的Java環境入門(瞭解) 1.2.1訪問物件的方法 1.2.2訪問物件的靜態方法 1.2.3獲得root中的資料

struts2框架的概述之問題一:什麼是

1. 問題一:什麼是值棧? * 值棧就相當於Struts2框架的資料的中轉站,向值棧存入一些資料。從值棧中獲取到資料。 * ValueStack 是 struts2 提供一個介面,實現類 OgnlValueStack ---- 值棧物件 (OGNL是從值棧中獲取資料的 ) * Acti