zoukankan      html  css  js  c++  java
  • (转) STRUTS2中的OGNL

    OGNL表达式是(Object-Graph Navigation Language)是对象图形化导航语言。OGNL是一个开源的项目,struts2中默认使用OGNL表达式语言来显示数据。与serlvet中的el表达式的作用是一样的。OGNL表达式有下面以下特点:

    1. 支持对象方法调用,例如:objName.methodName();
    2. 支持类静态的方法调用和值访问,表达式的格式为
      • @[类全名(包括包路经)]
      • @[方法名 |  值名]
      • 例如:
      • @java.lang.String@format('foo%s','bar')
      • @tutorial.MyConstant@APP_NAME;
    3. 支持赋值操作和表达式串联,例如: 
      • price=100, discount=0.8, calculatePrice(),这个表达式会返回80;
    4.  访问OGNL上下文(OGNL context)和ActionContext
    5.  操作集合对象
    类图
    ValueStack
    1.  ValueStack是一个接口,在struts2中使用OGNL表达式实际上是使用实现了ValueStack接口的类OgnlValueStack,这个类是OgnlValueStack的基础。
    2. ValueStack贯穿整个action的生命周期。每一个action实例都拥有一个ValueStack对象。其中保存了当前action对象和其他相关对象。
    3.  Struts2把ValueStack对象保存中名为struts.valueStack的request域中。
    ValueStack内存图
    ValueStack的组织结构
     
     

     从图上可以看出OgnlValueStack和我们有关的内容有两部分:即OgnlContext和CompoundRoot。所以把这两部分搞清楚很重要。

    总图

    说明:

    1. 上图是ognl完整的数据结构图,可以清晰得看出数据的组成。
    2. Context中的_root和ValueStack中的root(对象栈)里的数据结构和值是一样的。
    3. 这就意味着我们只需要操作OgnlContext就可以完成对数据的存和取的操作。
    4. ValueStack内部有两个逻辑的组成部分:
      •  ObjectStack
        • Struts会把动作和相关的对象压入到ObjectStack中。
      • ContextMap
        • Struts会把一些映射关系压入到ContextMap中
    OGNL Context
    1. 上图为OGNL Context的结构图
    2. 当struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action压入到值栈中。所以action的实例变量可以被ognl访问。所以利用ognl表达式可以访问action。
    ActionContext

    从上面的代码中可以看出来,struts2中的ActionContext的作用是提供了对ognl数

    据的操作。并且可以通过ActionContext获取到经过struts2封装了的session等参数。

    ServletActionContext
    1. 可以通过ServletActionContext得到servlet中的一些类,比如HttpServletRequest,ServletContext等
    2. 可以通过ServletActionContext返回ActionContext
    Ognl表达式
     
    1.#号用法
    1.  访问OGNL上下文和action上下文,#相当于ActionContext.getContext();
    2. 如果访问的是map中的值而不是对象栈中的值,由于map中的数据不是根对象,所以在访问时需要添加#前缀。

    名称

    作用

    例子

    parameters

    包含当前HTTP请求的Map

    #parameters.id[0]=request.getParameter(“id”)

    request

    包含当前HttpServletRequest属性的Map

    #request.username=request.getAttribute(“username”);

    session

    包含当前HttpSession属性的Map

    #session.username=session.getAttribute(“username”);

    application

    包含当前ServletContext属性的Map

    #application.username=application.getAttribute(“username”);

    attr

    用于按照request>session>application顺序访问其属性

    #attr.username相当于按照顺序在以上三个范围内读取username的属性,直到找到为止。

    注:也可以写为#request[‘username’]  #sesssion[‘username’]  #application[‘username’]

    主要步骤:

    在action中

    在页面中

    2.用法2

    OGNL会设定一个对象(root对象),在struts2中根对象就是CompoundRoot,或者为OgnlValueStack中的root,通常被叫做ValueStack(值栈或者对象栈),如果要访问根对象的属性,则可以省略去#,直接访问对象的属性即可。

    在action中

    在页面中

    <s:property value="msg"/>

    3.用法3(深入理解对象栈)

    有三个类:Person.Java,Student.java,OgnlAction.java

    Person类
    Student类
    OgnlAction类
    把Person类和Student类创建出对象,然后放入到对象栈中,代码为:
     
     

    从以前学过的OGNLContext结构可以看出,对象栈中的分布如图所示:

    但是大家注意一个现象:在student对象中有comment属性,在person对象中

    也有comment属性,在OgnlAction中还有comment属性,如果页面输出

    Comment属性应该选择哪种呢?

    结论:

    对于对象栈中存放的属性,struts2会从最顶部开始寻找,如果找到则赋值,
    如果找不到,则会依次往下寻找,直到找到为止。所以应该输出的是student

    对象的comment的值。

    4.用法4(构造map)

    还可以利用ognl表达式构造Map,如#{‘foo1’:’bar1’,’foo2’:’bar2’};这种用法经常用

    在给radio,checkbox等标签赋值上。

    1、 在页面上可以这样输出:

    2、 也可以这样使用:

    5.用法5(%)

    “%”符号的用途是在标签的属性值给理解为字符串类型时,执行环境%{}中添加的是OGNL表达式。

    {}中用OGNL表达式

    6.用法6($)

    $主要有两个用途:

    用于在国际化资源文件中引用OGNL表达式

    在struts2的配置文件中引用OGNL表达式

    在action中:

    在配置文件中:


    在页面中:

    标签

    Property标签

    1. default:
      • 可选属性,如果输出的值为null,则显示该属性指定的值。
    2. escape
      • 可选属性,指定是否格式化为html代码
    3.  value
      • 可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值。

    Debug标签

    利用debug标签可以输出OGNLContext所有的值

    Set标签

    1. var:
      • 变量的名字,name、id与var表达的含义是一样的。Var已经取代了name,id;
    2. Scope:
      • 指定变量被放置的范围。该属性可以接受application,session,request,page或Action。如果没有设置该属性,则默认会放在action中。
    3. Value:
      • 赋值给变量的值。如果没有设置该属性,则将ValueStack栈顶的值赋给变量。

    Push标签

    把对象放入到栈顶,不能放入到其他的范围,当标签结束时,会从栈顶删除。

    Bean标签

    实例化一个符合javabean规范的class,标签体内可以包含几个param元素,可用于调用set方法,给class的属性赋值。

    1. Name:
      • 要被实例化的class的名字,符合javabean规范。
    2. Var:
      • 赋值给变量的值。放置在request作用域中。如果没有设置该属性,对象被设置到栈顶。

    Action标签

    通过指定命名空间和action的名称,可以直接调用后台的action.

    1. Name:
      • Aciton的名字
    2. Namespace:
      • Action所在的命名空间(action的名称后不加.action)
    3. executeResult:
      • Action的result是否需要被执行,默认值为false,不执行

    Iterator标签

    该标签用于对集合进行迭代。这里的集合包括:list,set和数组

    1. Value:
      • 可选属性,指定被迭代的集合。如果没有设置该属性,则使用对象栈顶的集合。
    2. Var:
      • 可选属性,引用变量的名称
    3.  Status:
      • 可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下的方法:
        1. int getCount() 返回当前迭代的元素个数
        2. int getIndex() 返回当前迭代元素的索引
        3. boolean isEven() 返回当前迭代元素的索引是否是偶数
        4. boolean isOdd()  返回当前迭代元素的索引是否是奇数
        5. boolean isFirst()  返回当前迭代元素是否为第一个元素
        6. boolean isLast()  返回当前迭代元素是否为最后一个元素

    If/else if/else标签

    基本的流程控制标签。If标签可以单独使用,也可以结合elseif或else标签使用。

    1. test:
      • 后面跟判断表达式。

    url标签

    该标签用于创建url,可以通过”param”标签提供request参数。

    1. Value:
      • 如果没有值,就用当前的action,使用value后必须加.action.
    2. Action:
      • 用来生成url的action.如果没有使用则用value;
    3. Namespace:
      • 命名空间
    4. Var:
      • 引用变量的名称。

    Ognl操作集合

    Java代码

    OGNL表达式

    list.get(0)

    List[0]

    array[0]

    array[0]

    ((User)list.get(0)).getName()

    list[0].name

    Array.length

    Array.length

    List.size()

    List.size

    List.isEmpty()

    List.isEmpty

     

    Ognl操作Map

    Java代码

    Ognl表达式

    map.get(“foo”)

    Map[‘foo’]

    Map.get(new Integer(1));

    Map[1]

    User user = (User)map.get(“user”);

    Return user.getName()

    Map[‘user’].name

    Map.size()

    Map.size

    Map.isEmpty()

    Map.isEmpty

    Map.get(“foo”)

    Map.foo

      

    Java代码

    Ognl表达式

    Map map = new HashMap();

    Map.put(“foo”,”bar”);

    Map.put(“1”,”2”);

    Return map;

    #{“foo”:”bar”,”1”:”2”}

    Map map = new HashMap();

    Map.put(new Integer(1),”a”);

    Map.put(new Integer(2),”b”);

    Map.put(new Integer(3),”c”);

    #{1

  • 相关阅读:
    数据结构学习(十二)、归并排序
    数据结构学习(十一)、堆排序
    数据结构学习(十)、插入排序
    数据结构学习(九)、简单选择排序
    数据结构学习(八)、冒泡排序
    天梯赛 L3-013 非常弹的球 找规律
    codeup模拟赛 进击的二叉查找数
    POJ 2828 Buy Tickets 线段树 倒序插入 节点空位预留(思路巧妙)
    HDU 1394 逆序数 线段树单点跟新 | 暴力
    HDU 2795 Billboard 线段树,区间最大值,单点更新
  • 原文地址:https://www.cnblogs.com/hq233/p/6576902.html
Copyright © 2011-2022 走看看