Struts2-OGNL与值栈

值栈

  1. 可以从值栈中获取栈对象
    使用${productName}获取值,实际上该属性并不在request等域对象中,而是从值栈中获取的。
  2. 值栈分为两部分

    • Map栈:实际上是OgnlContext类型,是个Map,也是对ActionContext的一个引用。里面保存着各种Map:requestMap,sessionMap,applicationMap,paramtersMap,attr;

      • parameters: 该 Map 中包含当前请求的请求参数
      • request: 该 Map 中包含当前 request 对象中的所有属性
      • session: 该 Map 中包含当前 session 对象中的所有属性
      • application:该 Map 中包含当前 application 对象中的所有属性
      • attr: 该 Map 按如下顺序来检索某个属性: request, session, application
    • 对象栈:实际上是CompoundRoot类型,是一个使用ArrayList定义的栈。里面保存各种和当前Action实例相关的对象。是一个数据结构任意的对象。

OGNL

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

property 标签

Struts 的 property 标签用来输出值栈中的一个属性值.
Struts2-OGNL与值栈_第1张图片

读取 ObjectStack 里的对象的属性

  • 若想访问 ObjectStack 里的某个对象的属性. 可以使用以下几种形式之一:
object.propertyName
object['propertyName']
object["propertyName"]
  • ObjectStack 里的对象可以通过一个从零开始的下标来引用. ObjectStack 里的栈顶对象可以用 [0] 来引用, 它下面的那个对象可以用 [1] 引用. 若希望返回栈顶对象的 message 属性值: [0].message[0]["message"][0]['message']
  • 若在指定的对象里没有找到指定的属性, 则到指定对象的下一个对象里继续搜索. 即 [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象
  • 若从栈顶对象开始搜索, 则可以省略下标部分

读取 Context Map 里的对象的属性

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

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

示例:
1. 返回 session 中的 code 属性: #session.code
2. 返回 request 中的 customer 属性的 name 属性值: #request.customer.name
3. 返回域对象(按 request, session, application 的顺序)的 lastAccessDate 属性: #attr.lastAccessDate

调用字段和方法

  • 可以利用 OGNL 调用
    • 任何一个 Java 类里的静态字段或方法.
    • 被压入到 ValueStack 栈的对象上的公共字段和方法.
  • 默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置 struts.ognl.allowStaticMethodAccess 标记变量的值为 true.
  • 调用静态字段或方法需要使用如下所示的语法:
    • @fullyQualifiedClassName@fieldName: @java.util.Calendar@DECEMBER
    • @fullyQualifiedClassName@methodName(argumentList): @app4.Util@now()
  • 调用一个实例字段或方法的语法, 其中 objectObject Stack 栈里的某个对象的引用:
    • .object.fieldName: [0].datePattern
    • .object.methodName(argumentList): [0].repeat(3, “Hello”);

访问数组类型的属性

  • 有些属性将返回一个对象数组而不是单个对象, 可以像读取任何其他对象属性那样读取它们. 这种数组型属性的各个元素以逗号分隔, 并且不带方括号
  • 可以使用下标访问数组中指定的元素: colors[0]
  • 可以通过调用其 length 字段查出给定数组中有多少个元素: colors.length
value="#attr.names.length"/>

value="#attr.names[2]"/>

访问 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”}

访问 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}

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

也可以通过 JSP EL 来达到目的: ${fieldName}
原理: Struts2 将包装 HttpServletRequest 对象后的 org.apache.struts2.dispatcher.StrutsRequestWrapper 对象传到页面上, 而这个类重写了 getAttribute() 方法.

EL 能做的OGNL都能做,但是OGNL能做的,EL不一定能做。

<s:debug>s:debug>
<br/>
利用$ { name }获取<br/>
NAME:${name }<br/>
DESC:${desc }<br/>
PRICE:${price }<br/>
<br/>
获取字段和方法<br/>
PI:<s:property value="@java.lang.Math@PI"/><br/>
COS(0):<s:property value="@java.lang.Math@cos(0)"/><br/>
person.show():<s:property value="[0].show()"/>

<br/>
读取 ValueStack 里的对象的属性<br/>
DESC:<s:property value="[1].desc"/><br/>

<br/>
读取 Context Map 里的对象的属性<br/>
DESC:<s:property value="#session.person.desc"/><br/>
<%
String[] str = {"value","stack","object"};
request.setAttribute("str", str);
%>
<br/>
访问数组类型的属性<br/>
LENGHT:<s:property value="#request.str.length"/><br/>
OBJECT:<s:property value="#request.str[1]"/><br/>

<br/>
<br/>
访问Map类型的属性<br/>
LENGHT:<s:property value="#request.map.size()"/><br/>
isEmpty:<s:property value="#request.map.isEmpty()"/><br/>
OBJECT:<s:property value="#request.map.get('Liu')"/><br/>

你可能感兴趣的:(Java,随笔随记,框架,struts2)