要想了解ognl表达式,那么就要先了解ActionContext上下文,
这就是ActionContext的上下文目录结构。
ValueStack是上下文的根目录,所有的action中的参数,变量等都会加入到ValueStack中,在valueStack中其实是有有一个list结构的root对象,我们加入的对象和属性变量什么的都会保存在其中。
例如我们定义了一个person和production,当我们new person(id,name)和new production(name,price)时,这两个对象都会被加到root[new person ,new production]
当我们使用struts2标签来访问ognl时:
<s:proporty value="name" /> 这时ognl表达式会有一个查询顺序,那就是从根目录开始查询属性,所以这样的查询下来我们得到的属性值会是person.name属性,这是因为我们在action中定义的属性是会添加到valueStack这个根目录中。
其实当我们要使用ognl表达式来访问属性时,一般都要只用#范围,例如:
<s:proporty value="#request.name" />
在这里我们加上了#,这是因为只有在根目录中的属性和参数,才可以直接使用属性名来访问。
假设我们写了这样一个程序:
public class UseOgnlAction {
public String useognl(){
ActionContext act = ActionContext.getContext();
act.put("request", "request");
act.getSession().put("session", "session");
return "success";
}
}
在这里我们使用了ActionContext在request方法放入两个参数。
public String useognl(){
ActionContext act = ActionContext.getContext();
act.put("request", "request");
act.getSession().put("session", "session");
ServletActionContext.getRequest().getSession().setAttribute("requestSession", "requestSession");
ServletActionContext.getRequest().setAttribute("ServletRequset", "ServletRequset");
return "success";
jsp中我们可以这样访问:
request:<s:property value="request" /><br/>
ServletRequest:${ServletRequset}<br/>
session:<s:property value="#session.session" /><br/>
requestSession:<s:property value="#session.requestSession" /><br/>
所以说只有栈顶的可以省略#直接访问
关于ognl表达式创建list和map
<s:set var="list" value="{'first','second','third'}" />
<s:set var="map" value="#{'key1':'first','key2','second','key3':'third'}"/>
<s:iterator value="#list">
<s:property/><br/>
</s:iterator>
<s:iterator value="#map">
<s:property value="key"/> = <s:property value="value"/>
</s:iterator>
在这里我们使用<s:set var value />创建一个list, 使用<s:iterator >来迭代
当我们创i建了这个list或map时,这个list和map是存放在ActionContext的同一层目录中,就是和valueStack、request、application同一层目录中, 所以当我们访问时要使用#进行访问。
在进行<s:iterator />进行访问时,这个访问时,会将变量保存在ActionContext的栈顶之中,
<s:property/>不指定value时,会访问栈顶。
但是当我们访问迭代map时,存在栈顶的是:entry对象,这个对象会有key和value属性。所以当我们访问map的key和value时,直接在value中访问就ok了