OGNLでの使用Struts2の式

今日、共有は、2つの主要な目的は学ぶために、OGNL式言語Struts2のフレームワークです

      1 。プライオリティ値パスStruts2のを理解します

      差2.ognlとエル

A:OGNL式の言語の入門

  OGNLの略オブジェクトグラフナビゲーション言語(オブジェクトグラフナビゲーション言語)、それは強力な表現言語である、あなたは、シンプルで一貫性のある表現構文を通じてJavaオブジェクトのプロパティ値を読み込み、設定することができ、オブジェクトのメソッド呼び出し図は、変換を達成するために、オブジェクト全体、フィールドタイプの構造を横断します。 

  1.1:のための簡単な  例図のナビゲーション解析対象言語

     このプロジェクトは現在、2つのエンティティクラスを持っている場合:

   クラスブック(書籍クラスには、次の属性があります):

    プライベート文字列の入札。
    プライベート文字列BNAME。
    プライベートカテゴリーC;

   クラス分類(図書の分類は以下の属性があります):   

     プライベート文字列CID;
      プライベート文字列名;

  私は需要がある場合:

    同じカテゴリのJSPページ内の情報の本や書籍を表示したいです、

    いつものように、そして確かにそれは、JSP内のEL式をリストで出力を受け取り、書き込みBookDaoのコレクションです

         $ {book.bid} / $ {} book.bname

      しかし、$ {book.c.bname}は、ナビゲーション言語のオブジェクト図

2:OGNL表現言語機能 

  このような形態のような1サポート対象のメソッド呼び出し、:objName.methodName();

  2.サポートクラスの静的メソッドの呼び出しやアクセスの値は、フォーマット式として@ [(パッケージの道を含む)完全な名前を入力] | [メソッド名値の名前]たとえば、:

    @ java.lang.Stringで@追加( '11'、 'hahhaha')

  3.のような割り当てや表現シリーズをサポートしています:

   数= 18、価格= 100、合計(); 1800戻されます。

  4.アクセスOGNLコンテキスト(OGNLコンテキストが)、実際に地図(教室、教師、学生)とするactionContextです

    OgnlContext =ルートオブジェクト(1)+非ルート・オブジェクト(N)
    教師:ルートオブジェクト
    学生:オブジェクトN非ルート「#key」アクセスを介して非ルート・オブジェクトは、ルートオブジェクト「#key」を省略してもよいです
    

    3. 4.1:非ルートとルートオブジェクトオブジェクトの概要

      図1は、文脈が唯一のルートオブジェクトで
      、ルートオブジェクトを直接属性のみによって撮影されたオブジェクトの値と、2
      3、値は、非ルート・オブジェクトでなければならない。フェッチコンテキスト#keyコンテナによって指定された属性。

    グラフィック:

    

  OGNL値の割り当て方法:

  OnglExpressionクラス

package com.ht.text;

import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

/**
 * 用于OGNL表达计算的一个工具类
 * 
 */
public class OnglExpression {
    private OnglExpression() {
    }

    /**
     * 根据OGNL表达式进行取值操作
     * 
     * @param expression
     *            ognl表达式
     * @param ctx
     *            ognl上下文
     * @param rootObject
     *            ognl根对象
     * @return
     */
    public static Object getValue(String expression, OgnlContext ctx, Object rootObject) {
        try {
            return Ognl.getValue(expression, ctx, rootObject);
        } catch (OgnlException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 根据OGNL表达式进行赋值操作
     * 
     * @param expression
     *            ognl表达式
     * @param ctx
     *            ognl上下文
     * @param rootObject
     *            ognl根对象
     * @param value
     *            值对象
     */
    public static void setValue(String expression, OgnlContext ctx, Object rootObject, Object value) {
        try {
            Ognl.setValue(expression, ctx, rootObject, value);
        } catch (OgnlException e) {
            throw new RuntimeException(e);
        }
    }
}

四:值栈ValueStack 

  valueStack是struts2的值栈空间,是struts2存储数据的空间

  根据栈的制度,它是先进后出的数据结构,弹夹 push/pop

  之所以把它作为根对象主要是因为  放到值栈中的对象都可视为根对象

  4.1:ValueStack简介

  4.1.1.ValueStack是一个接口,在struts2中使用OGNL(Object-Graph Navigation Language)表达式实际上是使用实现了ValueStack接口的类OgnlValueStack.

  4.1.2.ValueStack贯穿整个action的生命周期,每一个action实例都拥有一个ValueStack对象,其中保存了当前action对象和其他相关对象.

  4.1.3.struts2把ValueStack对象保存在名为:struts.valueStack的request域中.即ValueStack作用域为request.当action创建的时候,ValueStack就创建了,action被销毁的时候,ValueStack就销毁了

  4.1.4.ValueStack中的数据分两部分存放:root(栈结构,CompoundRoot)和context(map形式,OgnlContext)

  (1)其中的root对象是CompoundRoot,CompoundRoot继承了ArrayList,提供了额外的方法:push(),和pop()方法,                 

用来对root对象中所包含的数据进行存取.正是由于这两个方法,CompoundRoot变成了一个栈结构. struts2中,一个请求在最终到达Action的方法之前,Action对象本身会被压入ValueStack(实际上就是放到ValueStack的CompoundRoot中),所以action对象是CompoundRoot中的一个元素.        

  (2)其中的context对象是OgnlContext,它实现了map接口,在valuestack的默认实现类中,即OgnlValueStack类中,                

调用ongl中的方法:Ognl.createDefaultContext(..)给context赋值,此方法返回的是一个OgnlContext对象.    

  ValueStack内存结构图如下:

  4.2 struts2中传递数据

  可以使用作用域,但更多的是利用ValueStackActionContext

  然而作用域取值有规律的他是从小到大的

   page -> request -> session -> application

  ActionContext就相当于一个大容器,同一请求中只创建一个上下文;

  ValueStack就是根对象容器,它的取值是从上至下的;

  parameters,request ,session ,application就是非根对象容器

  注意:

  1、ActionContext一次请求创建一次
  2、值栈取值从上往下,取到为止,如果已经拿到,不再往下找。

五:ognl与el区别

  因为OGNL表达式是struts2的默认表达式语言所以只对struts2标签管用,然而el在html中也可以用

   struts2标签用的都是ognl表达式语言,所以它多数都是去栈顶找值,找不到再去作用域

   el却相反,它都是去map集合作用域中找

  

 

  ognl的取值赋值案例示范

  

public class Demo1 {
 2 
 3     /**
 4      * @param args
 5      * @throws OgnlException
 6      */
 7     public static void main(String[] args)  {
 8 //        叫小李的员工
 9         Employee e = new Employee();
10         e.setName("小李");
11 //         张经理的管理
12         Manager m = new Manager();
13         m.setName("张经理");
14 
15         // 创建OGNL下文,而OGNL上下文实际上就是一个Map对象
16         OgnlContext ctx = new OgnlContext();
17 
18         // 将员工和经理放到OGNL上下文当中去
19         ctx.put("employee", e);
20         ctx.put("manager", m);
21 //        小李是根对象   一个公司有很多老板   只有一个员工小李
22         ctx.setRoot(e);// 设置OGNL上下文的根对象  
23 
24         /** ********************** 取值操作 *************************** */
25         // 表达式name将执行e.getName(),因为e对象是根对象(请注意根对象和非根对象表达式的区别)
26         String employeeName = (String) OnglExpression.getValue("name", ctx, e);
27         System.out.println(employeeName); //小李
28 
29         // 表达式#manager.name将执行m.getName(),注意:如果访问的不是根对象那么必须在前面加上一个名称空间,例如:#manager.name
30         String managerName = (String) OnglExpression.getValue("#manager.name",
31                 ctx, e);
32         System.out.println(managerName);  //张经理
33 
34         // 当然根对象也可以使用#employee.name表达式进行访问
35         employeeName = (String) OnglExpression.getValue("#employee.name", ctx,
36                 e);
37         System.out.println(employeeName);  //小李
38 
39         /** ********************** 赋值操作 *************************** */
40         OnglExpression.setValue("name", ctx, e, "小明");
41         employeeName = (String) OnglExpression.getValue("name", ctx, e);
42         System.out.println(employeeName);  //小明
43 
44         OnglExpression.setValue("#manager.name", ctx, e, "孙经理");
45         managerName = (String) OnglExpression.getValue("#manager.name", ctx, e);
46         System.out.println(managerName);  //孙经理
47 
48         OnglExpression.setValue("#employee.name", ctx, e, "小芳");
49         employeeName = (String) OnglExpression.getValue("name", ctx, e);
50         System.out.println(employeeName);  //小芳
51     }
52 }

  控制台上输出结果顺序与下面一致就对了

小李
张经理
小李
小明
孙经理
小芳

  ognl在struts2中的应用

  创建一个测试类

/**
     * 此例用于模拟struts2的值栈计算过程
     * ValueStack是一个堆栈结构的容器  有压栈操作   先进后出
     * @param args
     */
    public String test1(String[] args) {
        ValueStack vs =ServletActionContext.getContext().getValueStack();
        vs.push(new Employee("张雇员", 2000));// 1
        vs.push(new Student("小明同学", "s001"));// 0
        System.out.println(vs.findValue("name"));//小明
        System.out.println(vs.findValue("salary2")); //2000
        return "rs";
    }

  struts-sy.xml配置文件

<action name="/stack_*"  class="com.ht.text.Demo7" method="{1}">
            <result name="rs">/rs.jsp</result>
        </action>

jsp中代码

<a href="${pageContext.request.contextPath }/sy/stack_test1.action?sex=nv">ognl1</a>

输出结果为

小明同学
2000

现在来用实例证明一下ValueStack有压栈,先进后出的赋值套路

  创建一个类来写action代码,记得继承ModelDriven接口

private Cal cal1=new Cal();

    private String num1;

    public String getNum1() {
        return num1;
    }

    public void setNum1(String num1) {
        this.num1 = num1;
    }

    public String accept1() {
//        cal使用的是ModelDriven赋值
        System.out.println("cal1:"+cal1);
//        num使用的是get/set赋值
        System.out.println("num1:"+num1);
        return "rs";    
    }

jsp代码

<a href="${pageContext.request.contextPath }/sy/demo_accept1.action?num1=20&&num2=5">accept1</a>

输出结果

值栈中cal1变量比num1变量更靠近栈顶,所以她接收到了值,但是前台参数已经赋值,所以num1没有接收到值就为null了

 

今日分享到此结束,谢谢观看!

おすすめ

転載: www.cnblogs.com/huangting/p/11105051.html