Struts ognl

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、值栈取值从上往下,取到为止,如果已经拿到,不再往下找。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值