博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Struts2 学习系列 (4) ValueStack和OGNL
阅读量:7111 次
发布时间:2019-06-28

本文共 4253 字,大约阅读时间需要 14 分钟。

hot3.png

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
@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的内容为:

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"; } 
页面jsp的内容:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %>    
Insert title here Hello World!
username:
password:
Hello.action
请求参数中的用户名:
<%request.setAttribute("username", "request中的username"); %> 请求属性中的用户名:
会话属性中的用户名:
应用属性中的用户名:
attr中的账号:
7:访问静态方法和静态属性
在OGNL中,可以通过关键字"@"来访问任意类中的静态方法和静态属性,方式为"@类的全路径名@属性名称",或者"@类的全路径名@方法名称(方法参数)",如果在高版本的Struts2中,要访问类的静态方法,需要去开启设置,配置非常简单,在struts.xml中,添加开启访问类的静态方法的配置,如下所示:
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() 方法.

转载于:https://my.oschina.net/gaoguofan/blog/753197

你可能感兴趣的文章
2019春总结作业
查看>>
hashMap与hashTable的区别
查看>>
Synchronized关键字
查看>>
第五组用户使用情况报告
查看>>
轻松搞定面试中的红黑树问题
查看>>
在更新过程中,玩家存储空间满了的处理办法
查看>>
php discuz框架接口不能正常访问的问题
查看>>
ORACLE恢复误删的表数据
查看>>
mysql查询当天,前一天,一周,一个月
查看>>
Python学习一:序列基础详解
查看>>
数组排序
查看>>
Recycleview实现复杂布局
查看>>
jq禁止与启动滚动条
查看>>
ffmpeg去水印
查看>>
JSF通过超链接传递参数到控制层
查看>>
C#入门篇-3:数据类型及转换
查看>>
Leetcode Simplify Path
查看>>
Kafka吞吐量测试案例
查看>>
easyui datagrid 前后台代码
查看>>
洛谷P1416 进攻火星 数学
查看>>