Struts2 的 OGNL
ONGL简介:
OGNL 的全称是对象图导航语言( Object-Graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可以通过某种表达式语法,存储 java 对象的任意属性,调用 java 对象的方法,同时能够自动实现必要的类型转换。如果把表达式看作是一种带有语义的字符串,那么 OGNL 无疑成为了这个语义字符串于 java 对象之间的沟通桥梁。
OGNL的要素
表达式:表达式是整个OGNL的核心,OGNL会根据表达式去对象中取值,所有的OGNL操作都是指对表达式解析后进行的。它表明了此次OGNL操作要做什么。表达式就是一个带有语法含义的字符串,这个字符串规定了操作的类型和操作的内容。OGNL支持大量的表达式语法,不仅支持这种“链式”对象访问路径,还支持在表达式中进行简单的计算。
根对象(ROOT):Root对象可以理解为OGNL的操作对象,表达式规定了“做什么”,而Root对象则规定了“对谁操作"。OGNL称为对象图导航语言,所谓对象图,就是以任意对象为根,通过OGNL可以访问这个对象关联的其他。
Context对象:实际上OGNL的取值还需一个上下文环境,设置了Root对象,OGNL可以对root对象进行取值或者写值等操作,root对象所在环境就是OGNL的上下文环境(Context)。上下文环境规定了OGNL的操作”在哪里进行“。上下文环境COntext是一个map类型的对象,在表达式中访问Context中的对象,需要使用”#”号加上对象名称,即“#对象名称”的形式。
OGNL的取值与赋值方法
1 /**
2 * 用于OGNL表达计算的一个工具类
3 *
4 */
5 public class OnglExpression {
6 private OnglExpression() {
7 }
8
9 /**
10 * 根据OGNL表达式进行取值操作
11 *
12 * @param expression
13 * ognl表达式
14 * @param ctx
15 * ognl上下文 map
16 * @param rootObject
17 * ognl根对象
18 * @return
19 */
20 public static Object getValue(String expression, OgnlContext ctx,
21 Object rootObject) {
22 // ${book.c.name} 意味着你要在jsp上获取书籍的类别的名称 ctx.get(#name) 根对象取值
23 // ctx.get(${book.c.name}) 非根对象取值
24 try {
25 return Ognl.getValue(expression, ctx, rootObject);
26 } catch (OgnlException e) {
27 throw new RuntimeException(e);
28 }
29 }
30
31 /**
32 * 根据OGNL表达式进行赋值操作
33 *
34 * @param expression
35 * ognl表达式
36 * @param ctx
37 * ognl上下文
38 * @param rootObject
39 * ognl根对象
40 * @param value
41 * 值对象
42 */
43 public static void setValue(String expression, OgnlContext ctx,
44 Object rootObject, Object value) {
45 try {
46 Ognl.setValue(expression, ctx, rootObject, value);
47 } catch (OgnlException e) {
48 throw new RuntimeException(e);
49 }
50 }
51 }
EL表达式和OGNL的区别:
OGNL表达式只对struts标签管用,在HTML标签中还是要使用EL表达式
struts2标签中都是用的OGNL表达式,先从栈顶找,找不到就从map域中找,再找不到直接报错
而常规EL表达式只能从map域中找,不能在栈顶找,找不到什么都不显示。
搜索顺序为:page>request>session>application
但是struts2对HttpRequest对象进行了封装StrutsRequestWrapper,此时EL表达式可以在栈顶搜索
搜索顺序为:page>request>ValueStack>session>application
OGNL的取值与赋值案列
1 public class Demo1 {
2
3 /**
4 * @param args
5 * @throws OgnlException
6 */
7 public static void main(String[] args) {
8 // 叫小李的员工
9 Employee e = new Employee();
10 e.setName("小李");
11 // 张经理的管理
12 Manager m = new Manager();
13 m.setName("张经理");
14
15 // 创建OGNL下文,而OGNL上下文实际上就是一个Map对象
16 OgnlContext ctx = new OgnlContext();
17
18 // 将员工和经理放到OGNL上下文当中去
19 ctx.put("employee", e);
20 ctx.put("manager", m);
21 // 小李是根对象 一个公司有很多老板 只有一个员工小李
22 ctx.setRoot(e);// 设置OGNL上下文的根对象
23
24 /** ********************** 取值操作 *************************** */
25 // 表达式name将执行e.getName(),因为e对象是根对象(请注意根对象和非根对象表达式的区别)
26 String employeeName = (String) OnglExpression.getValue("name", ctx, e);
27 System.out.println(employeeName); //小李
28
29 // 表达式#manager.name将执行m.getName(),注意:如果访问的不是根对象那么必须在前面加上一个名称空间,例如:#manager.name
30 String managerName = (String) OnglExpression.getValue("#manager.name",
31 ctx, e);
32 System.out.println(managerName); //张经理
33
34 // 当然根对象也可以使用#employee.name表达式进行访问
35 employeeName = (String) OnglExpression.getValue("#employee.name", ctx,
36 e);
37 System.out.println(employeeName); //小李
38
39 /** ********************** 赋值操作 *************************** */
40 OnglExpression.setValue("name", ctx, e, "小明");
41 employeeName = (String) OnglExpression.getValue("name", ctx, e);
42 System.out.println(employeeName); //小明
43
44 OnglExpression.setValue("#manager.name", ctx, e, "孙经理");
45 managerName = (String) OnglExpression.getValue("#manager.name", ctx, e);
46 System.out.println(managerName); //孙经理
47
48 OnglExpression.setValue("#employee.name", ctx, e, "小芳");
49 employeeName = (String) OnglExpression.getValue("name", ctx, e);
50 System.out.println(employeeName); //小芳
51 }
52 }
输出结果:

OGNL在struts2中的应用
public String test1() {
// ValueStack是一个堆栈结构的容器 有压栈操作 先进后出
ValueStack vs = ServletActionContext.getContext().getValueStack();
vs.push(new Employee("张雇员", 2000));// 1
vs.push(new Student("小明同学", "s001"));// 0
System.out.println(vs.findValue("name")); //小明
System.out.println(vs.findValue("salary")); //2000
return "rs";
}
配置文件设置:
<action name="/stack_*" class="com.liuwenwu.test.DemoAction" method="{1}">
<result name="rs">/rs.jsp</result>
</action>
jsp代码:
<a href="${pageContext.request.contextPath }/sy/stack_test1.action?sex=nv">ognl1</a>
输出结果:

证明ValueStack是一个堆栈结构的容器 有压栈操作 先进后出
valueStack的赋值套路
private Cal cal1=new Cal();
private String num1;
public String getNum1() {
return num1;
}
public void setNum1(String num1) {
this.num1 = num1;
}
public String accept1() {
// cal使用的是ModelDriven赋值
System.out.println("cal1:"+cal1);
// num使用的是get/set赋值
System.out.println("num1:"+num1);
return "rs";
}
jsp代码:
<a href="${pageContext.request.contextPath }/sy/demo_accept1.action?num1=20&&num2=5">accept1</a>
输出结果:

cal1有值而num1没值 cal1通过ModelDriven接口赋值 num1通过get/set方法赋值 最终压栈的结构 num1在下 cal1在上 所以赋值在cal1上 不会赋值到底部的num1上 所以num1为 null
Struts2 的 OGNL的更多相关文章
- Struts2的OGNL表达式语言
一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...
- Struts2之OGNL
一.OGNL是什么? OGNL(Object-Graph Navigation Language)对象图导航语言,是一种表达式语言,它可以 1.遍历对象的结构图 2.存取对象的属性(实例属性和静态属性 ...
- Struts2对Ognl的支持
Struts2对Ognl的支持 一. 写作背景 由于工作性质的变化,最近一直在研究struts2,从 ...
- Struts2的OGNL标签详解
一.Struts2可以将所有标签分成3类: UI标签:主要用于生成HTML元素的标签. 非UI标签:主要用于数据库访问,逻辑控制等标签. Ajax标签:用于Ajax支持的标签. 对于UI标签,则有可以 ...
- struts2之OGNL和struts2标签库和ValueStack对象
OGNL简介: (1)OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. struts2框架默认就支持Ognl表达式语言(所以 ...
- 2018.11.25 struts2与OGNL表达式的结合(高级)
两者的结合原理 底层源码分析 栈原理 先进后出 我们的valuestack其实是一个接口 在实现类中有这个参数 CompoundRoot的类继承的是ArrayList,具体实现弹栈和压栈的方法具体实现 ...
- 【Struts2】Ognl与ValueStack
一.OGNL 1.1 概述 1.2 OGNL 五大类功能 1.3 演示 二.ValueStack 2.1 概述 2.2 ValueStack结构 2.3 结论 2.3 一些问题 三.OGNL表达式常见 ...
- JavaWeb_(Struts2框架)Ognl小案例查询帖子
此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...
- Struts2与OGNL的联系
1.Struts与OGNL的结合原理 (1)值栈: OGNL表达式要想运行就要准备一个OGNLContext对象,Struts2内部含有一个OGNLContext对象,名字叫做值栈. 值栈也由两部分组 ...
- Struts2之OGNL与ValueStack
时间:2017-1-12 12:02 --OGNL1.OGNL表达式是什么 OGNL的全称是Object-Graph Navigation Language的缩写,中文名是对象图导航语言,它是一 ...
随机推荐
- jsp-->js-->jsp之间的关系
jsp和js通过form.submit();发送request请求createdIdSave.jsp 在CreatedIdSave.jsp中进行BL的增删改查操作,在jsp中将值保存到页面的scrip ...
- Java大整形BigInteger的用法
基本类型int有32位,范围是:[-2147483648, 2147483647](正负21亿多) 基本类型long有64位,范围是:[-9223372036854775808, 9223372036 ...
- 计算机网络part2——物理层
物理层概述 1.物理层基本概念 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体. 主要任务:确定与传输媒体接口有关的一些特性 特性: 机械特性 电气特性 功能特性 规 ...
- XSS闯关挑战(1-15)
第一关 关键代码: 这一关两处的输出都没做任何防护,直接将用户的输入拼接到输出里面. payload: 第二关 使用上一关的payload显示如下 闭合一下标签就好了. 第三关 htmlspecial ...
- 了解CSS in JS(JSS)以及在React项目中配置并使用JSS
目录 认识JSS 什么是JSS JSS 的常见实现 JSS 的好处与坏处 好处 坏处 使用模块化CSS实现JSS 安装插件 在React项目中的tsconfig.json中添加配置 vscode项目中 ...
- 慕慕生鲜上线&&腾讯云服务器配置准备
1.购买服务器并配置环境 1.1 购买 618购买了腾讯云服务器三年最低配置(1核2G 1Mbps 50G云盘),一时激动忘记了购买前领优惠券,痛失25元. 1.2 环境配置 系统是 CentOS L ...
- CentOS7 安装Oracle12c数据库
在centos7上安装oracle是一个比较麻烦的事,在安装前需要做一些服务器的准备工作 我是在虚拟机里测试的所以需要下载centos7的镜像,可以去官网然后找到中国的镜像站用迅雷插件下载速度比较快这 ...
- 利用VAR模型科学管理仓位,提升策略效率
更多精彩内容,欢迎关注公众号:数量技术宅,也可添加技术宅个人微信号:sljsz01,与我交流. 期货行情瞬息万变,保证金体系决定了期货交易的杠杆属性.保证金放多了,资金利用率低,放少了,可能在大幅度的 ...
- NOIP 模拟 9 斐波那契
题解 这是一道推规律的题. 首先,这道题送分不少,先考虑 \(70pts\),直接暴力 \(\mathcal O(n)\) 建边,\(\mathcal O(logn)\) 求 \(lca\) 其次对于 ...
- 题解—P2218 [HAOI2007]覆盖问题
一道不错的题,主要就是一个思路点,想到就行了,想不到就一直卡着. 看完题解之后发现挺简单,实际上自己挣扎半天也咩有想到. 一开始想类比成一维之后贪心,后来被同机房大佬 \(hack\) 掉了. sol ...