天天看点

(五)Struts2——OGNLOGNL

OGNL

一、值栈

我们在struts——helloWorld中的示例程序中,使用了

${productName}

读取productName 值,实际上该属性并不在request 等域对象中,而是从值栈中获取的。

值栈,ValueStack:

可以从ActionContext中获取值栈对象。

值栈可以分为两个逻辑部分:

  • Map栈:实际上是OgnlContext类型。也是对ActionContext的一个引用。里面保存各种Map:

    requestMap

    ,

    sessionMap

    ,

    applicationMap

    ,

    parametersMap

    ,

    attr

    .
  • 对象栈:实际上是CompoundRoot类型,是一个使用ArrayList定义的栈。里面保存着各种和当前Action实例相关的对象。是一个数据结构意义的栈。

ValueStack(值栈): 贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象.

Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中。

在 ValueStack 对象的内部有两个逻辑部分:

  • ObjectStack: Struts 把 Action 和相关对象压入 ObjectStack 中
  • ContextMap: Struts 把各种各样的映射关系(一些 Map 类型的对象) 压入 。ContextMap 中. 实际上就是对 ActionContext 的一个引用

Struts 会把下面这些映射压入 ContextMap 中

  • parameters: 该 Map 中包含当前请求的请求参数
  • request: 该 Map 中包含当前 request 对象中的所有属性
  • session: 该 Map 中包含当前 session 对象中的所有属性
  • application:该 Map 中包含当前 application 对象中的所有属性
  • attr: 该 Map 按如下顺序来检索某个属性: request, session, application
    (五)Struts2——OGNLOGNL

二、OGNL

在 JSP 页面上可以可以利用 OGNL(Object-Graph Navigation Language: 对象-图导航语言) 访问到值栈(ValueStack) 里的对象属性。

若希望访问值栈中 ContextMap 中的数据,需要给OGNL表达式加上一个前缀字符

#

。如果没有前缀字符#,搜索将在ObjectStack里进行。

1. property标签

Struts 的 property 标签用来输出值栈中的一个属性值.

(五)Struts2——OGNLOGNL

jsp文件上面需要导入标签库:

<%@ taglib prefix="s" uri="/struts-tags" %>
           

2. 读取ObjectStack里对象的属性

  • 想要访问ObjectStack里对象的属性。可以使用以下几种形式之一:
    object.propertyName
    object['propertyName']
    object["propertyName"]
               
  • ObjectStack 里的对象可以通过一个从零开始的下标来引用。 ObjectStack 里的栈顶对象可以用 [0] 来引用, 它下面的那个对象可以用 [1] 引用.。若希望返回栈顶对象的 message 属性值:

    [0].message

    [0]["message"]

    [0]['message']

    ,结合property标签,可以写成:

    <s:property value="[0].message" />

    或者

    <s:property value="message" />

  • 若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象
  • 若从栈顶对象开始搜索, 则可以省略下标部分
默认情况下,Action 对象会被Struts2自动的放到值栈的栈顶。

3. 读取Context Map栈里面的属性

若想访问 ContextMap 里的某个对象的属性, 可以使用以下几种形式之一:

#object.propertyName
#object['propertyName']
#object["propertyName"]
           

示例:

  • 返回 session 中的 code 属性:

    #session.code

  • 返回 request 中的 customer 属性的 name 属性值:

    #request.customer.name

  • 返回域对象(按 request, session, application 的顺序)的 lastAccessDate 属性:

    #attr.lastAccessDate

4. 调用字段和方法

可以利用 OGNL 调用

  • 任何一个 Java 类里的静态字段或方法.
  • 被压入到 ValueStack 栈的对象上的公共字段和方法.

默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置

struts.ognl.allowStaticMethodAccess

标记变量的值为 true.

调用静态字段或方法需要使用如下所示的语法:

  • @[email protected]:

    例如:

    @[email protected]

  • @[email protected](argumentList):

    例如:

    @[email protected]()

调用一个实例字段或方法的语法, 其中 object 是 Object Stack 栈里的某个对象的引用:

  • object.fieldName:

    [0].datePattern

  • object.methodName(argumentList):

    [0].repeat(3, “Hello”);

5. 访问数组类型的属性

  • 有些属性将返回一个对象数组而不是单个对象, 可以像读取任何其他对象属性那样读取它们。这种数组型属性的各个元素以逗号分隔, 并且不带方括号。
  • 可以使用下标访问数组中指定的元素:

    colors[0]

  • 可以通过调用其 length 字段查出给定数组中有多少个元素:

    colors.length

6. 访问List类型的数组

  • 有些属性将返回的类型是 java.util.List, 可以像读取任何其他属性那样读取它们. 这种 List 的各个元素是字符串, 以逗号分隔, 并且带方括号
  • 可以使用下标访问 List 中指定的元素:

    colors[0]

  • 可以通过调用其 size 方法或专用关键字 size 的方法查出给定List 的长度:

    colors.size

    colors.size()

  • 可以通过使用 isEmpty() 方法或专用关键字 isEmpty 来得知给定的 List 是不是空.

    colors.isEmpty

    colors.isEmpty()

  • 还可以使用 OGNL 表达式来创建 List, 创建一个 List 与声明一个 Java 数组是相同的:

    {“Red”, “Black”, “Green”}

7. 访问Map类型的属性

  • 读取一个 Map 类型的属性将以如下所示的格式返回它所有的键值对:
    { key-1=value-1, key-2=value-2,... key-n=value-n,}
               
  • 若希望检索出某个 Map 的值, 需要使用如下格式:

    map[key]

  • 可以使用

    size

    size()

    得出某个给定的 Map 的键值对的个数
  • 可以使用

    isEmpty

    isEmpty()

    检查某给定 Map 是不是空.
  • 可以使用如下语法来创建一个 Map:
    #{ key-1:value-1, key-2:value-2,... key-n:value-n,}
               

8. 使用EL访问值栈中对象的属性

<s:property value=“fieldName”>

也可以通过 JSP EL 来达到目的:

${fieldName}

原理: Struts2 将包装

HttpServletRequest

对象后的

org.apache.struts2.dispatcher.StrutsRequestWrapper

对象传到页面上, 而这个类重写了

getAttribute()

方法.

END.