OGNL的结构示意图如下:
GNL Context---------{ValueStack(值栈,它是跟对象), parameters,request,session,application,attr}
当struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action存进ValueStack,所以action的实例变量可以被OGNL访问
OGNL用一个上下文(Context)概念,也就是一个map结构,它实现了java.util.Map接口。ONGLContext与ActionContext是两个不同的类。ActionContext.getContext().getContextMap().get("session")等同于ActionContext.getContext().getSession()。
访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application,#session。OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中的对象的属性,则可以省略#命名空间。直接访问该对象的属性即可。
在struts2中,根对象ValueStack的实现类为OgnlValueStack,在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象,在root变量中处于第一位的对象是栈顶对象。通常我们在OGNL表达式里直接写上属性的名称就可以访问root变量里的对象属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就依次往下寻找,直到找到为止。Struts2中,OGNL表达式需要配合Struts2标签才可以使用。
如:<s: property value="name"/>。
由于ValueStack(值栈)是struts2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面直接通过EL表达式访问ValueStack(值栈)中对象的属性。EL表达式能够访问ValueStack中的对象是因为Struts2对HttpServletRequest作了进一步的封装。
如果需要一个集合元素的时候(List集合或者Map集合),可以使用OGNL中同集合相关的表达式。使用如下代码直接生成一个List对象
- <s:set name="list" value="{'zhangsan','lisi','wangwu'}" />
- <s:iterator value="#list" >
- <s:property/><br>
- </s:iterator>
<s:set>标签用于将某个值放入指定范围。该标签的scope属性指定变量被放置的属性,该属性可以接受application,session,request,page或action。如果没有设置该属性,默认放置在OGNL Context中。value属性是赋给变量的值,如果没有设置该属性,则将ValueStack栈顶的值赋值给变量。
生成一个Map对象
- <!-- 如果Map集合的value是数字不需要加'' -->
- <s:set name="map" value="#{'username':'go123', 'password':123456}" />
- <s:iterator value="#map" >
- <s:property value="key"/> = <s:property value="value"/> <br>
- </s:iterator>
"%"符号的用途是计算OGNL表达式的值。<s:url>的 value属性默认把值当做字符串处理,要想计算OGNL表达式的值可以用“%{xxx}”来表示。例如下面的例子:
- <s:set name="google" value="http://www.google.com.hk"></s:set>
- <s:url value="#google"></s:url><br/>
- <s:url value="%{#google}"></s:url>