您的位置:首页 > 编程语言 > Java开发

对struts2的OGNL的理解

2014-05-10 22:20 369 查看
OGNL:Object-Graph Navigation Language.对象图形化导航语言

OGNL是集成进struts2框架中比较强大的技术有助于数据传输和类型转换,OGNL由表达式语言和类型装换器组成。

表达式语言:

我们已经在jsp表单input名和jsp标签使用该语言了.他用来绑定java端的数据属性和基于字符串的

视图层表示.表达式语言甚至可以进行方法调用,目的就在于方便数据访问.大多数时候OGNL表达式不

需要转义,如需转义的话,需要用到%{表达式}符号.框架会把它按照表达式来处理而不是解释成字符

串语义.

下面是ognl的类图:



说明:

1.ValueStack是一个接口,在struts2中使用OGNL表达式实际上是使用实现了ValueStack接口的类OgnlValueStack,这个类是OgnlValueStack的基础。

2.ValueStack贯穿整个action的生命周期。每一个action实例都拥有一个ValueStack对象。其中保存了当前action对象和其他相关对象。(内部底层其实是用ThreadLocal实现Action范围内数据共享)

3.Struts2把ValueStack对象保存中名为struts.valueStack的request域中。

下面是ValueStack的图解:



说明:

1,上图是ognl完整的数据结构图,可以清晰得看出数据的组成。

2,Context中的_root和ValueStack中的root(对象栈)里的数据结构和值是一样的。

3,这就意味着我们只需要操作OgnlContext就可以完成对数据的存和取的操作。

4,ValueStack内部有两个逻辑的组成部分:

a,ObjectStac

Struts会把动作和相关的对象压入到ObjectStack中。

b,ContextMap

Struts会把一些映射关系压入到ContextMap中

向map中存数据

1, ServletActionContext.getRequest().setAttribute("req_username","req_username");

ServletActionContext.getRequest().setAttribute("req_psw", "req_psw");

ActionContext.getContext().getSession().put("session_username", "session_username");

ActionContext.getContext().getSession().put("session_psw", "session_psw");

2,ActionContext.getContext().put("data", "aaaaaaaaaaaaaaaaa");

向值栈中存数据

1,

/*

* 把对象放入到值栈中

*/

//方法一:先得到root,把一个对象压入到root中

ValueStack valueStack = ActionContext.getContext().getValueStack();

valueStack.getRoot().add(new Person());

valueStack.getRoot().add(new Student());

2,

/*

* 方法二:先得到root,利用add(index,Object)把一个对象压入到root中

* 这里index指的是集合中的位置

*/

ValueStack valueStack = ActionContext.getContext().getValueStack();

valueStack.getRoot().add(new Person());

valueStack.getRoot().add(0, new Student());

3,

/*

* 方法三:

* 把一个键值对存放在对象栈中

*/

ValueStack valueStack = ActionContext.getContext().getValueStack();

valueStack.set("msg","msg_object");

4,

/*

* 方法4

* 利用ValueStack的push方法可以把一个对象直接压入对象栈的第一个位置

*/

ValueStack valueStack = ActionContext.getContext().getValueStack();

valueStack.push(new Person());

OGNL Context图解:



1,上图为OGNL Context的结构图

2,当struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action压入到值栈中。所以action的实例变量可以被ognl访问。所以利用ognl表达式可以访问action。

3,ActionContext是Action执行时的上下文,上下文可以看作是一个map容器(其实我们这里的容器就是一个Map而已),存放Action在执行时需要用到的对象。而ServletActionContext(com.opensymphony.webwork. ServletActionContext),这个类直接继承了ActionContext,它提供了直接与JavaServlet相关对象访问的功能,如下代码:

Map session = ActionContext.getContext().getSession();

HttpSession session = ServletActionContext. getRequest().getSession();

4,每次请求都会创建一个Action,执行Action之前都会创建新的ActionContext,ActionContext是线程安全的,也就是说在同一个线程里ActionContext里的属性是唯一的,这样Action就可以在多线程中使用。

OGNL表达式:

1,访问OGNL上下文和action上下文,#相当于ActionContext.getContext();

2,如果访问的是map中的值而不是对象栈中的值,由于map中的数据不是根对象,所以在访问时需要添加#前缀。



Demo:

在Action中:

public String testScope() {

// 把字符串"request_msg"放入到request域中

ServletActionContext.getRequest().setAttribute("request_username","request_username");

// 把字符串"session_msg"放入到session域中

ServletActionContext.getRequest().getSession().setAttribute("session_username", "session_username");

// 把字符串"application_msg"放入到application域中

ServletActionContext.getServletContext().setAttribute("application_username", "application_username");

return "ognl_scope";

}

页面中:

ognl表达式关于scope(request,session,application)的输出<br>

request:<s:property value="#request.request_username"/><br>

session:<s:property value="#session.session_username"/><br>

application:<s:property value="#application.application_username"/><br>

3,OGNL会设定一个对象(root对象),在struts2中根对象就是CompoundRoot,或者为OgnlValueStack中的root,通常被叫做ValueStack(值栈或者对象栈),如果要访问根对象的属性,则可以省略去#,直接访问对象的属性即可。

Demo:

在Action中:

public String testObjectValue(){

//得到ognl的上下文

ValueStack valueStack = ActionContext.getContext().getValueStack();

valueStack.set("msg", "object_msg");

return "ognl_objectstack";

}

在页面中:

对象栈的内容:<s:property value="msg"/>

//把对象栈中key值为msg的value的值输出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: