OGNL是Object Graphic Navigation Language 是操做对象属性的开源表达式。 Struts2框架使用OGNL做为默认的表达式语言。html
在学习JSP的时候,咱们已经学习过了EL表达式。EL表达式用起来也十分简单...咱们在Struts2框架中也是可使用EL表达式的...那么OGNL表达式好在哪里呢??java
OGNL是Struts2的默认表达式语言,OGNL是配搭Strut2的标签使用的..咱们学习了OGNL表达式,就能够更好地理解Struts2标签的运行以及Struts2内部的存储结构.微信
在讲解OGNL表达式以前,咱们先来看看valueStack对象...valueStack是Struts2数据存储的核心...咱们首先要知道数据是怎么存的,存到哪里,而后才讲解OGNL表达式是怎么取出数据的。session
valueStack也被称做值栈对象..app
//获取值栈对象的2种方式
private void getVs() {
// 获取值栈对象,方式1:
HttpServletRequest request = ServletActionContext.getRequest();
ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");
// 获取值栈对象,方式2:
ActionContext ac = ActionContext.getContext();
ValueStack vs2 = ac.getValueStack();
System.out.println(vs1 == vs2);//true
}
复制代码
上面已经说了,用户访问Action时,会建立Action对象,valueStack对象。Struts2内部会将Action对象存到valueStack对象之中...那么valueStack的存储结构是什么样的呢???咱们来看看框架
Action对象和Action的成员属性等值都是存到CompoundRoot下的.该CompoundRoot继承着ArrayList,所以它是List结构的学习
public class CompoundRoot extends ArrayList {}
复制代码
OgnlContext对象存储着相关的域对象:request、response、session等数据,实现Map集合,是Map结构..编码
为了让request、response等域对象能够存储多个值,值也是使用Map结构...spa
public class OgnlContext implements Map {}
复制代码
CompoundRoot保存着这样的数据:debug
OgnlContext保存着这样的数据:
也就是说经过OgnlContext对象能够获取大部分咱们须要的数据了。
那么OGNL表达式是怎么取出OgnlContext对象中数据的呢??下面咱们经过硬编码的方式来说解:
/** * 1. Ognl表达式语言语言取值,取非根元素的值,必须用#号 * @throws Exception */
@Test
public void testOgnl() throws Exception {
// 建立一个Ognl上下文对象
OgnlContext context = new OgnlContext();
// 放入数据
User user = new User();
user.setId(100);
user.setName("Jack");
// 【往非根元素放入数据, 取值的时候表达式要用"#"】
context.put("user", user);
// 获取数据(map)
// 先构建一个Ognl表达式, 再解析表达式
Object ognl = Ognl.parseExpression("#user.name");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
/** * 2. Ognl表达式语言语言取值,取根元素的值,不用带#号 * @throws Exception */
@Test
public void testOgn2() throws Exception {
// 建立一个Ognl上下文对象
OgnlContext context = new OgnlContext();
// 放入数据
User user = new User();
user.setId(100);
user.setName("Jack");
// 【往根元素放入数据】
context.setRoot(user);
// 获取数据(map)
// 先构建一个Ognl表达式, 再解析表达式
Object ognl = Ognl.parseExpression("address.province");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
复制代码
也就是说,JSP页面中取出数据的时候,它会先构建一个OGNL表达式,再解析表达式
<!-- 页面: 必需要拿到ValueStack -->
<br/>1. 取根元素的值<br/>
<s:property value="user.id"/>
<s:property value="user.name"/>
<s:property value="user.address"/>
<s:property value="user.address.city"/>
<s:property value="user.address.province"/>
<br/>2. 取非根元素的值<br/>
<s:property value="#request.cn"/>
<s:property value="#session.Session_data"/>
<s:property value="#application.Application_data"/> <br/>
<!-- 自动找request/session/application,找到后马上返回 -->
<s:property value="#request_data"/>
<s:property value="#attr.Session_data"/>
<s:property value="#attr.Application_data"/> <br/>
<!-- 获取请求的参数数据 -->
<s:property value="#parameters.userName"/>
<!-- struts的调试标签:能够观测值栈数据 -->
<s:debug></s:debug>
复制代码
/** * 3.Ognl对 静态方法调用的支持 * @throws Exception */
@Test
public void testOgn3() throws Exception {
// 建立一个Ognl上下文对象
OgnlContext context = new OgnlContext();
// Ognl表单式语言,调用类的静态方法
//Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
// 因为Math类在开发中比较经常使用,因此也能够这样写
Object ognl = Ognl.parseExpression("@@floor(10.9)");
Object value = Ognl.getValue(ognl, context, context.getRoot());
System.out.println(value);
}
复制代码
<br/>1、.构建 list集合</br>
<s:iterator var="str" value="{'a','b'}">
<s:property value="#str"/>
</s:iterator>
<br/>1、.构建 map集合</br>
<s:iterator var="en" value="#{'cn':'China','usa':'America'}">
<s:property value="#en.key"/>
<s:property value="#en.value"/> <br/>
</s:iterator>
复制代码
构建Map集合的时候,须要使用#号
#OGNL 几个特殊的符号#
#获取非根元素值 、 动态都建map集合 $ 在配置文件取值 % 提供一个ognl表达式运行环境
<body>
<br/>获取request域数据<br/>
<!-- property 标签是对象类型的标签,默认支持ognl表达式, 会从根元素去China名称对应的值 -->
<s:property value="China"/> <br/>
<!-- 若是直接赋值,须要用单引号 -->
<s:property value="'China'"/> <br/>
<s:property value="%{#request.cn}"/> <br/>
<!-- 值类型的标签,value值默认就是值类型,不支持ognl表达式 -->
国家:<s:textfield name="txtCountry" value="%{#request.cn}"></s:textfield>
</body>
复制代码
若是文章有错的地方欢迎指正,你们互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:Java3y