OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts使用OGNL作为默认的表达式语言。OGNL提供了平时我们需要的一些功能,如:支持对象方法调用、支持各类静态方法调用和值访问,支持操作集合对象等。OGNL有一个上下文的概念,这个上下文实质就是一个Map结构,实现了java.utils.Map接口。
ValueStack(值栈)
ValueStack实际上是一个接口,struts2中的OGNL其实是使用了实现了该接口的一个OgnlValueStack类,此类是使用struts2中的OGNL表达式的基础。
1.ValueStack值栈是贯串整个Action实例对象的生命周期,每个Action实例都有自己的值栈,在其中存放在当前Action对象中的各种其它类型的对象数据;
2.struts2从内部结构上有两大逻辑组成部分:
(1)ObjectStack:把处理动作相关的对象压入栈中,结果是个List集合对象
(2)contextMap:把各种映射压入其中,具体有:
parameters :包含请求的所有参数
request :request所有的属性
session : session所有的属性
application : application所有的属性
attr:按顺序来检索某个属性: request--session--application
OGNL Context(GONL上下文)
1.OGNLValueStack类有两个重要的属性:root和context,root其实就是一个ArrayList,context其实就是一个Map,也可以说是ognlcontext的对象;
2.在ognlcontext对象中有个默认的顶层对象root,OGNL访问context中的顶层对象中的元素时,可以不使用#来访问,直接通过元素的名称来访问,而访问其他的对象时,则需要#,例如:request,session,application,attr等。
特意说明:root对象是OGNLValueStack的属性,struts2把他付给了OGNLContex对 象中属性root,同时保存着调用Action 的实例,所以在jsp中通过ognl表达式访问Action的属性时,就可以不通过#来访问<s:property value=“userName”/>,如果访问Map中的值就是需要#,<s:property value=“#request.userName”/>;
3.当struts2在接受一个请求后,第一时间创建ActionContext,ValueStack,action ,然后把 Action存放进ValueStack,所以我们可以通过ognl表达式访问action实例对象。同时在使用OGNL表达式需要配合Struts2标签才能够使用,
<s:property value=“userName”/>。
实例:
LoginAction.java中有以下对象和方法:
private User user;
private List myList = new ArrayList();
private Set mySet = new HashSet();
private Map myMap = new HashMap();
private List<Student> studentList = new ArrayList<Student>();
public String get() {
return "这是LoginAction中的get方法";
}
public static String getSta() {
return "这是LoginAction中的静态方法";
}
在jsp中获取属性代码如下:
<!-- 调用LoginAction中的User对象属性 -->
值栈中的username属性:<s:property value="user.username" /><br>
<!-- 调用LoginAction中的get方法 -->
调用LoginAction对象中的普通方法1: <s:property value="get()" /><br>
调用LoginAction对象中的普通方法2: <s:property value="%{get()}" /><br>
<!-- 调用LoginAction中的getSta静态方法 -->
调用LoginAction对象中的静态方法1:
<s:property value="@com.ognl.LoginAction@getSta()" /><br>
调用LoginAction对象中的静态方法2: <s:property value="@vs@getSta()" /><br>
<!-- 调用User中的get方法 -->
调用值栈对象中的普通方法1: <s:property value="user.get()" /><br>
调用值栈对象中的普通方法2: <s:property value="user.username.length()" /><br>
<!-- 集合对象 -->
获取List:<s:property value="myList" /><br>
获取List中的第一个元素:<s:property value="myList[0] " /><br>
获取List的大小:<s:property value="myList.size()" /><br>
获取Set:<s:property value="mySet" /><br>
获取Set中的第一个元素:set无序,不能取到!<s:property value="mySet[0]" /><br>
获取Map:<s:property value="myMap" /><br>
获取Map中的Key=m1的元素的值方法1:<s:property value="myMap.m1" /><br>
获取Map中的Key=m1的元素的值方法2:<s:property value="myMap['m1']" /><br>
获取Map中所有键:<s:property value="myMap.keys" /><br>
获取Map中所有值:<s:property value="myMap.values" /><br>
<!-- 集合对象进阶 -->
获取List中的Student对象:<s:property value="studentList" /><br>
利用投影获取List中的name属性:<s:property value="studentList.{name}" /><br>
利用投影获取List中的age属性:<s:property value="studentList.{age}" /><br>
利用投影获取List中的第一个对象的name属性方法1:
<s:property value="studentList[0].name" /><br>
利用投影获取List中的第一个对象的name属性方法2:
<s:property value="studentList.{name[0]"/><br>
利用投影获取List中grade>70的student信息:
<s:property value="studentList.{?#this.grade>70}"/><br>
利用投影获取List中grade>70的student名字信息(?#取出符合条件的所有的对象):
<s:property value="studentList.{?#this.grade>70}.{name}"/><br>
利用投影获取List中grade>70的第一个student名字信息:
<s:property value="studentList.{?#this.grade>70}.{name}[0]" /><br>
利用投影获取List中grade>70的第一个student名字信息(^#取出符合条件的第一个对象):
<s:property value="studentList.{^#this.grade>70}.{name}" /><br>
利用投影获取List中grade>70的最后一个student名字信息($#取出符合条件的最后一个对象):
<s:property value="studentList.{$#this.grade>70}.{name}" /><br>
<!-- 获取Stack Context中的信息 -->
获取Request的属性:<s:property value="#request.req" /><br>
获取Session的属性:<s:property value="#session.ses" /><br>
获得parameters的属性:<s:property value="#parameters.mes" /><br>