文章目录
1. Struts2学习笔记三:OGNL表达式学习、Struts2与Ognl表达式的结合原理
1.1. 什么是OGNL表达式
- OGNL:对象视图导航语言,是比EL表达式有更加丰富的功能,EL表达式仅仅只有获取值的功能,而OGNL表达式还具有赋值的功能。
1.2. 使用OGNL表达式
- 导包
- Struts2包里面已经包含了,但他不是Struts2官方自己搞的,而是借用别人的。
- 从图中可以看出OGNL表达式操作的内容包含两个区,第一个是Root区,可以存放任何对象。第二个是Context区,只能存放Map键值对。
//准备Root
User rootUser = new User("tom",18);
//准备Context
Map<String,User> context = new HashMap<String,User>();
context.put("user1", new User("jack",18));
context.put("user2", new User("rose",22));
OgnlContext oc = new OgnlContext();
//将rootUser作为root部分
oc.setRoot(rootUser);
//将context这个Map作为Context部分
oc.setValues(context);
- 难点在于从root区和Context区取值问题。首先从Root区取值
String name = (String) Ognl.getValue("name", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("age", oc, oc.getRoot());
-
直接填写对象中的属性名就能取到值。
-
从Context区取值
String name = (String) Ognl.getValue("#user1.name", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user2.name", oc, oc.getRoot());
- 需要添加一个#号,#号代表Context域,user1表示取出user1为键的值,name为所要的值。
- 给Root域属性赋值,给Context域属性赋值
Ognl.getValue("name='jerry'", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user1.name='xxx',#user1.name", oc, oc.getRoot());
- 调用Root域中对象的setName()方法,调用Context域中对象的setName()方法方法
Ognl.getValue("setName('lilei')", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("#user1.setName('lucy'),#user1.getName()", oc, oc.getRoot());
- 调用静态方法
String name = (String) Ognl.getValue("@cn.zhang.a_ognl.HahaUtils@echo('hello 强勇!')", oc, oc.getRoot());
Double pi = (Double) Ognl.getValue("@java.lang.Math@PI", oc, oc.getRoot());
Double pi = (Double) Ognl.getValue("@@PI", oc, oc.getRoot());
- 调用静态方法要写@类路径名,然后@静态方法名。
- 创建list对象
Integer size = (Integer) Ognl.getValue("{'tom','jerry','jack','rose'}.size()", oc, oc.getRoot());
String name = (String) Ognl.getValue("{'tom','jerry','jack','rose'}[0]", oc, oc.getRoot());
String name2 = (String) Ognl.getValue("{'tom','jerry','jack','rose'}.get(1)", oc, oc.getRoot());
- 就使用大括号的形式
- 创建Map对象
Integer size2 = (Integer) Ognl.getValue("#{'name':'tom','age':18}.size()", oc, oc.getRoot());
String name3 = (String) Ognl.getValue("#{'name':'tom','age':18}['name']", oc, oc.getRoot());
Integer age = (Integer) Ognl.getValue("#{'name':'tom','age':18}.get('age')", oc, oc.getRoot());
1.3. Struts2和ONGL表达式的结合原理
- OGNL表达式是由一个OGNLContext域来维护的,Struts2需要与ONGL表达式结合,就要创建一个域OGNLContext表达式一样的域,叫ValueStack值栈。
- 值栈里面包含两个域,即root部分和Context域,Context域是由键值对来维护的。
- 栈原理
- 先进后出,进栈,出栈。栈是由ArrayList模拟的。
- 栈由两个方法,压栈,和弹栈
//弹栈,弹出第0个值
public Object pop(){
return remove(0);
}
//压栈,压到第0个位置
public Object push(Object o){
add(0,o);
}
3. 通过DeBug标签查看值栈中的内容
- jsp页面
<%@ taglib prefix="s" uri="/struts-tags" %><!--导入标签库-->
<body>
<!-- 调试标签 -->
<s:debug></s:debug>
</body>
- 会显示值栈中的两部分内容,Root和Context,Root值栈中默认情况下存放当前访问的Action对象。
- Context部分就是ActionContext数据中心,里面包含request,response等Servlet9大域对象内容
- struts2和ognl结合体现
- 参数接收-属性驱动
- 对象驱动
- 模型驱动
- 可以通过ONGL表达式配置动态struts.xml文件
<action name="Demo3Action" class="cn.zhang.d_config.Demo3Action" method="execute" >
<result name="success" type="redirectAction" >
<param name="actionName">Demo1Action</param>
<param name="namespace">/</param>
<!-- 如果添加的参数struts"看不懂".就会作为参数附加重定向的路径之后.
如果参数是动态的.可以使用${}包裹ognl表达式.动态取值
-->
<param name="name">${name}</param>
</result>
- 例如http://localhost:8080/Demo1Action?name=zhang
- request对象的getAttribute()方法