概述
1.Ognl表达式语言
1.1.概述
OGNL表达式
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个开源项目。Struts框架使用OGNL作为默认的表达式语言。
1.2.OgnlContext对象(了解)
OgnlContext对象是ognl表达式语言的核心。
但是项目中不会要求写OgnlContext的代码,Ognl标签其实是调用了OgnlContext对象。所以只做了解即可。
OgnlContext对象在源码中实现了Map接口:
public class OgnlContext implements Map {……}
1
Ognl表达式语言取值,也是用java代码取值的,原理就是使用OgnlContext和Ognl这两个类,只需要记住,Ognl取根元素不用#号,取非根元素要使用#号:
OgnlContext类
硬编码方式,了解OgnlContext对象,因为OgnlContext对象实现是Map接口,所有OgnlContext本质就是一个Map,可以使用map方法:
OgnlContext context = new OgnlContext();
context.put(“uesr”,user);
context.put(“address”,address);
context.setRoot(address);
1
2
3
4
Ognl类
Ognl类也是Ognl底层运行的代码,常用的api如下:
Object obj1 = Ognl.parseExpression(“country”); 解析ognl表达式
Ognl.getValue(obj1, context, context.getRoot()); 获取ognl的表达式值,obj1是上面一个api,
其他两个分别是创建的上下文对象以及一个不用修改的参数
Object obj2 = Ognl.parseExpression(“language.toUpperCase()”); 方法调用
Object obj3 = Ognl.parseExpression("@java.lang.Integer@toBinaryString(10)");等同于上面
Object obj4 = Ognl.parseExpression(“@@min(10,4)”); Math类的方法直接调用,静态方法的调用
1
2
3
4
5
6
7
代码示例:
import ognl.OgnlContext;
import ognl.OgnlException;
public class Demo1 {
/**
* @param args
* @throws OgnlException
*/
public static void main(String[] args) {
Employee e = new Employee();
e.setName(“小李”);
Manager m = new Manager();
m.setName("张经理");
// 创建OGNL下文,而OGNL上下文实际上就是一个Map对象
OgnlContext ctx = new OgnlContext();
// 将员工和经理放到OGNL上下文当中去
ctx.put("employee", e);
ctx.put("manager", m);
ctx.setRoot(e);// 设置OGNL上下文的根对象
/** ********************** 取值操作 *************************** */
// 表达式name将执行e.getName(),因为e对象是根对象(请注意根对象和非根对象表达式的区别)
String employeeName = (String) OnglExpression.getValue("name", ctx, e);
System.out.println(employeeName);
// 表达式#manager.name将执行m.getName(),注意:如果访问的不是根对象那么必须在前面加上一个名称空间,例如:#manager.name
String managerName = (String) OnglExpression.getValue("#manager.name",
ctx, e);
System.out.println(managerName);
// 当然根对象也可以使用#employee.name表达式进行访问
employeeName = (String) OnglExpression.getValue("#employee.name", ctx,
e);
System.out.println(employeeName);
/** ********************** 赋值操作 *************************** */
OnglExpression.setValue("name", ctx, e, "小明");
employeeName = (String) OnglExpression.getValue("name", ctx, e);
System.out.println(employeeName);
OnglExpression.setValue("#manager.name", ctx, e, "孙经理");
managerName = (String) OnglExpression.getValue("#manager.name", ctx, e);
System.out.println(managerName);
OnglExpression.setValue("#employee.name", ctx, e, "小芳");
employeeName = (String) OnglExpression.getValue("name", ctx, e);
System.out.println(employeeName);
}
}
重点:
1、一个上下文中只有一个根对象
2、取跟对象的值,只需要直接通过根对象属性即可
3、非根对象取值必须通过指定的上下文容器中的#key.属性去取。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
2. ValueStack
1.ValueStack即值栈对象
ValueStack实际是一个接口,在Struts2中利用Ognl时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用Ognl的基础
2.ValueStack特点
ValueStack贯穿整个Action的生命周期(每个Action类的对象实例都拥有一个ValueStack对象),即用户每次访问struts的action,都会创建一个Action对象、值栈对象、ActionContext对象,然后把Action对象放入值栈中;最后再把值栈对象放入request中,传入jsp页面。相当于一个数据的中转站,在其中保存当前Action对象和其他相关对象。Struts2框架把ValueStack对象保存在名为“struts。valueStack”的request请求属性中。
3.ValueStack存储对象
代码调试的时候,发现有一个root是compundRoot类,继承ArrayList,保存的是action对象;还有一个OgnlContext是继承Map,保存数据。
所以ValueStack存储对象时是分两个地方来存的,也即ValueStack对象的组成是由List栈和Map栈构成的:
ObjectStack:Struts把根元素,即action对象及全局属性存入ObjectStack中—List
list栈主要存储:action对象,Map对象(通过vs.set()设置),通过push方法设置的对象,以及其他代理对象
根元素的存储示例:
//存储值栈对象
ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
vs.set("user1",new User(100,"Jack1"));//Map
vs.push(new User(100,"Jack2"));//栈顶
1
2
3
4
5
6
ContextMap:Struts把各种各样的映射关系(域数据)存入ContextMap中
Struts会把下面这些映射存入ContextMap中:
parameter:该Map中包含当前请求的请求参数
request:该Map中包含当前request对象中的所有属性
Session:该Map中包含当前Session对象中的所有属性
application:该Map中包含当前application对象中的所有属性
attr:该Map按如下顺序来检索某个属性:request,Session,application
非根元素Map中存放数据的方法示例:
//存储值栈对象
ActionContext ac = ActionContext.getContext();
//映射数据
ac.getContextMap().put(“request_data”, “request_data”);
ac.getSession().put(“session_data”, “session_data”);
ac.getApplication().put(“application_data”,“application_data”);
1
2
3
4
5
6
从栈中取值的两种方式:
public 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
}
1
2
3
4
5
6
7
8
9
10
11
12
在jsp页面中,对不同ValueStack中的不同类型取值方法不同,
如果是根元素取值,直接写表达式;
非根元素(request,Session,application,att,parmeters)必须用#号,例#request.cnl
代码示例:
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.OgnlValueStack;
import com.opensymphony.xwork2.util.ValueStack;
public class Demo7 {
/**
*
* 值栈的使用
*
*/
public static void main1(String[] args) {
// 栈:表示一个先进后出的数据结构
ValueStack vs = new OgnlValueStack();
// push方法把项压入栈顶
vs.push(new Employee(“zs”, 22));
vs.push(new Employee(“ls”, 22));
vs.push(new Employee(“ww”, 22));
// pop方法移除栈顶对象并作为此函数的值返回该对象
Employee e = (Employee) vs.pop();
System.out.println(e.getName());
e = (Employee) vs.pop();
System.out.println(e.getName());
e = (Employee) vs.pop();
System.out.println(e.getName());
}
/**
* 此例用于模拟struts2的值栈计算过程
*
* @param args
*/
public static void main(String[] args) {
ValueStack vs = new OgnlValueStack();
vs.push(new Employee("张雇员", 2000));// 1
vs.push(new Student("小明同学", "s001"));// 0
System.out.println(vs.findValue("name"));
System.out.println(vs.findValue("salary2"));
ActionContext ac = ActionContext.getContext();
}
}
重点: 1、ActionContext一次请求创建一次
2、值栈取值从上往下,取到为止,如果已经拿到,不再往下找。
最后
以上就是认真钢笔为你收集整理的Struts ognl的全部内容,希望文章能够帮你解决Struts ognl所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复