Struts2 学习系列 (4) ValueStack和OGNL

1. 关于值栈:

1). helloWorld 时, ${productName} 读取 productName 值, 实际上该属性并不在 request 等域对象中, 而是从值栈中获取的.

此时的request是经过了strust2封装的,并不是原生的request.
2). ValueStack:

I. 可以从 ActionContext 中获取值栈对象
II. 值栈分为两个逻辑部分

> Map 栈: 实际上是 OgnlContext 类型, 是个 Map, 也是对 ActionContext 的一个引用. 里边保存着各种 Map:
requestMap, sessionMap, applicationMap, parametersMap, attr

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

2. Struts2 利用 s:property 标签和 OGNL 表达式来读取值栈中的属性值

1). 值栈中的属性值:

> 对于对象栈: 对象栈中某一个对象的属性值

> Map 栈: request, session, application 的一个属性值 或 一个请求参数的值.

2). 读取对象栈中对象的属性:

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

object.propertyName ; object['propertyName'] ; object["propertyName"]

> ObjectStack 里的对象可以通过一个从零开始的下标来引用. ObjectStack 里的栈顶对象可以用 [0] 来引用,
它下面的那个对象可以用 [1] 引用.

[0].message

> [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象

> 若从栈顶对象开始搜索, 则可以省略下标部分: message

> 结合 s:property 标签: <s:property value="[0].message" /> <s:property value="message" />

3). 默认情况下, Action 对象会被 Struts2 自动的放到值栈的栈顶.


2. OGNL:


1:OGNL是对象图导航语言(Object-Graph Navigation Language)的缩写, 它是一种功能强大的表达式语言(EL),通过它简单一致的表达式语法,可以存取对象的属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化功能,它用相同的表达式语法去存取对象的属性

 若希望访问值栈中 ContextMap 中的数据, 需要给 OGNL 表达式加上一个前缀字符 #. 如果没有前缀字符 #, 搜索将在 ObjectStack 里进行.

2:常量与操作符
<s:property value="'account''">,这里面的account是个字符串,因为是用单引号括起来的,或者<s:property value="7+8">这句话,结果就是15,也就是数学运算之后的值

3:方法调用
访问静态方法,访问集合对象的方法, 可以利用 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”);

如:<s:property value="@java.lang.Math@random()"/>

4.访问数组类型的属性

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

5:使用OGNL访问ValueStack

在OGNL中,没有前缀表示访问当前值栈。如<s:property valu="account">


6:使用OGNL访问ActionContext

在ognl中,使用符号"#"来访问ActionContext中除了值栈之外的各种值,如,

#parameters:当前请求中的参数,对应request.getParameter(name)

#request:请求作用域中的属性,对应request.getAttribute(name)

#session:会话作用域的属性,对应session.getAttribute(name)

#application:应用程序作用域的属性

#attr:按照页面page,请求request, 会话session和应用application的顺序,返回第一个符合条件的属性。

在引用的时候,需要加上前缀"#", 并制定范围,然后写出需要引用哪个属性,形如"#parameters.account"


在ognl中还有另外一种方式来访问属性,形如"#request['username']"等价于使用"#request.username",在访问更复杂对象的时候,两种方法可以混用。

一般情况下:如果访问对象的属性,建议使用"."的方式来改变,如果访问Map等复杂结构的时候,建议使用"[]"的方式来访问

action的内容为:

<span style="font-family:Microsoft YaHei;">public String execute() { 
System.out.println("用户输入的参数为,username:" + username + ", password:" + password); 

ActionContext context = ActionContext.getContext(); 
context.getSession().put("username", "session中的username"); 
context.getApplication().put("username", "application中的account"); 

return "success"; 

} </span>

页面jsp的内容:
<span style="font-family:Microsoft YaHei;"><%@ page language="java" contentType="text/html; charset=UTF-8" 
pageEncoding="UTF-8"%> 
<%@ taglib prefix="s" uri="/struts-tags" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Insert title here</title> 
</head> 
<body> 
Hello World!<br> 
username:<s:property value="username"/><br> 
password:<s:property value="password"/><br> 
<a href="hello.action?username=zhangsan" target="_self">Hello.action</a> 
<br/> 
请求参数中的用户名:<s:property value="#parameters.username"/> 
<br/> 
<%request.setAttribute("username", "request中的username"); %> 
请求属性中的用户名: <s:property value="#request.username"/> 
<br> 
会话属性中的用户名: <s:property value="#session.username"/> 
<br> 
应用属性中的用户名: <s:property value="#application.username"/> 
<br> 
attr中的账号: <s:property value="#attr.username"/> 
<s:debug></s:debug> 
</body> 
</html> </span>


7:访问静态方法和静态属性

在OGNL中,可以通过关键字"@"来访问任意类中的静态方法和静态属性,方式为"@类的全路径名@属性名称",或者"@类的全路径名@方法名称(方法参数)",如果在高版本的Struts2中,要访问类的静态方法,需要去开启设置,配置非常简单,在struts.xml中,添加开启访问类的静态方法的配置,如下所示:
<span style="font-family:Microsoft YaHei;"><constant name="struts.ognl.allowStaticMethodAccess" value="true" /></span>

8:使用ognl访问数组

OGNL表达式为:array.length,就表示访问array这个数组的length属性

list.size,表示访问list这个集合的size()方法

list.isEmpty,就表示访问list这个集合的isEmpth方法

OGNL表达式为{1, 2, 3},就表示构建一个包含3个值的集合,值分别为1, 2, 3

OGNL表达式为{1, 2, 3}[0],就表示构建一个包含3个值的集合,值分别是1, 2, 3, 然后获取索引为0的值,就是1.


9:访问map

在action中有属性: Map<String, UserModel> userMap = new HashMap<String, UserModel>();

在页面中:

用户编号:<s:property value="userMap['umTest'].userId">

用户姓名: <s:property value="userMap['umTest'].name">


OGNL表达式为:map.size, 就表示访问map这个Map的size
map.isEmpty, 就表示访问map这个Map的isEmpty方法


10.使用EL来访问变量

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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值