• Strust OGNL详解


    首先了解下OGNL的概念

    OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。

    此外,还得先需弄懂OGNL的一些知识:

    1.OGNL表达式的计算是围绕OGNL上下文进行的。
    OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。
    上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。
    2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。如:<s:propertyvalue="xxx"/>。
    3.Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。
    4.值栈(ValueStack) :
    可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。
    Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。
     
    5.调用ActionContext的put(key,value)放入的数据,需要使用#访问。

    OGNL中重要的3个符号:#、%、$:

    #、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分,需要时间的积累才渐渐弄清楚……
    1.#符号

    #符号的用途一般有三种。

    —    访问非根对象属性,例如#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当于ActionContext.getContext().getSession(). getAttribute("msg") 。

    —    用于过滤和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name=='pla1'}.{age}[0]。

    —    用来构造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。

    2.%符号

    %符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值,这个类似js中的eval,很暴力。

    3.$符号

    $符号主要有两个方面的用途。

    —    在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。

    ======================================================Strust2 中 OGNL堆栈的原理和实现=============================================================

     

    访问属性

    名字属性获取 :<s:property value="user.username"/><br>

    地址属性获取 :<s:property value="user.address.addr"/><br>

    访问方法

    调用值栈中对象的普通方法: <s:property value="user.get()"/><br>

    访问静态属性和方法

    调用 Action 中的静态方法: <s:property value="@struts.action.LoginAction@get()"/>

    调用 JDK 中的类的静态方法: <s:property value="@java.lang.Math@floor(44.56)"/><br>

    调用 JDK 中的类的静态方法 ( 同上 ) : <s:property value="@@floor(44.56)"/><br>

    调用 JDK 中的类的静态方法: <s:property value="@java.util.Calendar@getInstance()"/><br>

    调用普通类中的静态属性: <s:property value="@struts.vo.Address@TIPS"/><br>

    访问构造方法

    调用普通类的构造方法 :<s:property value="new struts.vo.Student(' 王老吉 ' , ' 爱国饮料 ' , 3 , 99).username"/>

    1.5. 访问数组

    获取 List:<s:property value="testList"/><br>

    获取 List 中的某一个元素 ( 可以使用类似于数组中的下标获取 List 中的内容 ):

    <s:property value="testList[0]"/><br>

    获取 Set:<s:property value="testSet"/><br>

    获取 Set 中的某一个元素 (Set 由于没有顺序,所以不能使用下标获取数据 ):

    <s:property value="testSet[0]"/><br> ×

    获取 Map:<s:property value="testMap"/><br>

    获取 Map 中所有的键 :<s:property value="testMap.keys"/><br>

    获取 Map 中所有的值 :<s:property value="testMap.values"/><br>

    获取 Map 中的某一个元素 ( 可以使用类似于数组中的下标获取 List 中的内容 ):

    <s:property value="testMap['m1']"/><br>

    获取 List 的大小 :<s:property value="testSet.size"/><br>

    访问集合 – 投影、选择 (? ^ $)

    利用选择获取 List 中成绩及格的对象 :<s:property value="stus.{?#this.grade>=60}"/><br>

    利用选择获取 List 中成绩及格的对象的 username:

    <s:property value="stus.{?#this.grade>=60}.{username}"/><br>

    利用选择获取 List 中成绩及格的第一个对象的 username:

    <s:property value="stus.{?#this.grade>=60}.{username}[0]"/><br>

    利用选择获取 List 中成绩及格的第一个对象的 username:

    <s:property value="stus.{^#this.grade>=60}.{username}"/><br>

    利用选择获取 List 中成绩及格的最后一个对象的 username:

    <s:property value="stus.{$#this.grade>=60}.{username}"/><br>

    利用选择获取 List 中成绩及格的第一个对象然后求大小 :

    <s:property value="stus.{^#this.grade>=600}.{username}.size"/><br>

    集合的伪属性

    OGNL 能够引用集合的一些特殊的属性 , 这些属性并不是 JavaBeans 模式 , 例如 size(),length() 等等 . 当表达式引用这些属性时 ,OGNL 会调用相应的方法 , 这就是伪属性 .

    集合

    伪属性

    Collection(inherited by Map, List & Set)

    size ,isEmpty

    List

    iterator

    Map

    keys , values

    Set

    iterator

    Iterator

    next , hasNext

    Enumeration

    next , hasNext , nextElement , hasMoreElements

      Lambda   :[…]

    格式: :[…]

    使用 Lambda 表达式计算阶乘 :

    <s:property value="#f = :[#this==1?1:#this*#f(#this-1)] , #f(4)"/><br>

    OGNL 中 # 的使用

    # 可以取出堆栈上下文中的存放的对象 .

    名称

    作用

    例子

    parameters

    包含当前 HTTP 请求参数的 Map

    #parameters.id[0] 作用相当于

    request.getParameter("id")

    request

    包含当前 HttpServletRequest 的属性( attribute) 的 Map

    #request.userName 相当于

    request.getAttribute("userName")

    session

    包含当前 HttpSession 的属性( attribute)的 Map

    #session.userName 相当于

    session.getAttribute("userName")

    application

    包含当前应用的 ServletContext 的属性(attribute )的 Map

    #application.userName 相当于

    application.getAttribute("userName")

    attr

    用于按 request > session > application 顺序访问其属性( attribute )

    获取 Paraments 对象的属性: <s:property value="#parameters.username"/>

    OGNL 中 % 的使用

    用 %{} 可以取出存在值堆栈中的 Action 对象 , 直接调用它的方法 .

    例如你的 Action 如果继承了 ActionSupport . 那么在页面标签中,用 %{getText('key')} 的方式可以拿出国际化信息 .

      OGNL 中 $ 的使用

    “ $ ”有两个主要的用途

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

    l          在 Struts 2 配置文件中,引用 OGNL 表达式

      值栈

    ValueStack 对象。这个对象贯穿整个 Action 的生命周期(每个 Action 类的对象实例会拥有一个 ValueStack 对象)。当 Struts 2 接收到一个 .action 的请求后,会先建立 Action 类的对象实例,但并不会调用Action 方法,而是先将 Action 类的相应属性放到 ValueStack 对象的顶层节点( ValueStack 对象相当于一个栈)。

    在 Action 中获得 ValueStack 对象: ActionContext.getContext().getValueStack()

    l          Top 语法

    使用 Top 获取值栈中的第二个对象 :<s:property value="[1].top. 对象 "/>

    l          N 语法

    使用 N 获取值栈中的第二个对象 :<s:property value="[1]. 对象 "/>

    l          @ 语法

    调用 action 中的静态方法: <s:property value="@vs1@ 静态方法 "/> vs :值栈 1 :表示第一个。

  • 相关阅读:
    C语言 sprintf 函数 C语言零基础入门教程
    C语言 printf 函数 C语言零基础入门教程
    C语言 文件读写 fgets 函数 C语言零基础入门教程
    C语言 文件读写 fputs 函数 C语言零基础入门教程
    C语言 fprintf 函数 C语言零基础入门教程
    C语言 文件读写 fgetc 函数 C语言零基础入门教程
    C语言 文件读写 fputc 函数 C语言零基础入门教程
    C语言 strlen 函数 C语言零基础入门教程
    Brad Abrams关于Naming Conventions的演讲中涉及到的生词集解
    适配器模式
  • 原文地址:https://www.cnblogs.com/hero96/p/5942919.html
Copyright © 2020-2023  润新知