一.OGNL
- 概述:Object-Graph Navigation Language 对象图导航语言
- EL: 从域对象中获取数据, 从EL的11个对象中获取
- OGNL: 调用对象的方法, 获取Struts2的值栈的数据, 是第三方的表达式语言
- 使用要素:
- 表达式
- root根对象
- Context对象
二.OGNL的Java环境入门
- 访问对象的方法
//获得context
OgnlContext context = new OgnlContext();
//获得根对象
Object root = context.getRoot();
//执行表达式
Object obj = Ognl.getValue(" 'helloworld'.length()", context, root);
System.out.println(obj); - 访问对象静态方法
//获得context
OgnlContext context = new OgnlContext();
//获得根对象
Object root = context.getRoot();
//执行表达式 @类名@方法名
Object obj = Ognl.getValue("@java.lang.Math@random()", context, root);
System.out.println(obj); - 获得Root中的数据
- 获得OGNLContext中的数据
三.OGNL的Struts2环境入门
- 访问对象的方法
<h3>调用对象的方法</h3>
<s:property value="'struts'.length()"/> - 访问对象的静态方法
<!-- 静态方法访问在Struts2中默认是关闭的,开启一个常量 -->
<s:property value="@java.lang.Math@random()"/>
在配置文件struts.xml中 配置常量<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
四.值栈 ValueStack
- 概述: ValueStack 类似于一个数据中转站(Struts2的框架当中的数据就都保存到了ValueStack中)
ValueStack接口,实现了OgnlValueStack对象
ValueStack贯穿整个Action的生命周期(Action一旦创建,框架就会创建一个ValueStack对象) - 内部结构
root区域 其实就是一个ArrayList 里面一般放置对象, 获取root的数据不需要加#
context区域 其实就是一个Map 里面放置是web开发的常用的对象数据的引用, 获取context的数据需要加#
操作值栈,通常指的是操作的ValueStack中的root区域 - 值栈与ActionContext的关系
ServletContext: Servlet的上下文
ActionContext : Action的上下文
ActionContext对象之所以能够访问Servlet的API(访问是域对象的数据),因为在其内部有值栈的引用 - 获取值栈
- - - 通过ActionContext对象获取值栈
ValueStack valueStack = ActionContext.getContext().getValueStack();
- - - 在Struts2的内部,将值栈存入request中一份
ValueStack valueStack = (ValueStack)ServletActionContext.getRequest().getAttribute("struts.valueStack"); - 操作值栈--向值栈中存入数据
- - - 在Action中提供属性的get方法的方式 , 默认情况下,将Action对象压入值栈,它的属性也会在值栈中
- - - 使用ValueStack中本身的方法的方式 push或者set - 获取值栈数据
- - - 获取值栈中的数据就是在页面中使用 OGNL表达式即可
- - - 获取root中数据 用push存 : <s: property value="username"/> 用set存 : <s:property value="list[0].username"/>
- - - 获取context中数据 <s:property value="#request.name"/> ...... - EL为何访问值栈数据
因为Struts2的框架的底层对request.getAttribute(String name)
五.OGNL中的特殊字符
- #号
- 获取context的数据
- 使用#号构建map集合
- %号
- 强制解析OGNL
<% request.setAttribute("name","张三"); %>
姓名:<s:textfield name="name" value="%{#request.name}"/> - 强制不解析OGNL
<s:property value="%{ ' #request.name ' }"/>
- 强制解析OGNL
- $号
- 在配置文件中使用OGNL
- - 属性文件 : 国际化
- - XML文件 : 文件下载
- 在配置文件中使用OGNL
六.综合案例: 优化查询
- 将查询到的数据存入到值栈中
//将查询到的list存入到值栈中
ActionContext.getContext().getValueStack().set("list", list); - 在页面中使用OGNL表达式