(五)Struts2——OGNL

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
    在这里插入图片描述

二、OGNL

在 JSP 页面上可以可以利用 OGNL(Object-Graph Navigation Language: 对象-图导航语言) 访问到值栈(ValueStack) 里的对象属性。
若希望访问值栈中 ContextMap 中的数据,需要给OGNL表达式加上一个前缀字符#。如果没有前缀字符#,搜索将在ObjectStack里进行。

1. property标签

Struts 的 property 标签用来输出值栈中的一个属性值. 在这里插入图片描述

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.

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

  • @fullyQualifiedClassName@fieldName:
    例如:@java.util.Calendar@DECEMBER
  • @fullyQualifiedClassName@methodName(argumentList):
    例如:@app4.Util@now()

调用一个实例字段或方法的语法, 其中 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.sizecolors.size()
  • 可以通过使用 isEmpty() 方法或专用关键字 isEmpty 来得知给定的 List 是不是空. colors.isEmptycolors.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]
  • 可以使用 sizesize() 得出某个给定的 Map 的键值对的个数
  • 可以使用 isEmptyisEmpty() 检查某给定 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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章