1.ValueStack
Struts2通过ValueStack来进行赋值与取值的。ValueStack是一个接口,而OgnlValueStack是strtus2中的缺省实现。ValueStack中的数据,分两个部分存放:root和context。同时ValueStack暴露相关的接口:
void setValue(String expr, Object value);Object findValue(String expr);用来通过OGNL表达式对ValueStack中的数据进行操作!
root在一些资料中叫做对象栈,之所以叫栈,因为它是一个栈结构,通过push()和pop()方法,对对象中所包含的数据进行存取!context其实是一个Map类型的对象。如果需要在表达式中访问更多没有导航关系的对象时,我们可以把他们放入Map中存储。通过put(k,v),get(k),进行存取。
我们结合一张图详细了解一下:
在我们访问一个action时,比如:xx.action?id=3&name=ab&age=20时,请求就经过一系列的拦截器。在这个过程中有对ValueStack create init,push(model),封装参数等。如上图。model中有两个属性id,name,xxaction中还有两个普通属性id,age.那传递过来的首页赋值给model中的id和name,model中找不到age,则会继续往下找,找到age并赋值。
我们在action中可以通过ActionContext.getContext.getValueStack()方法对ValueStack操作。若要对对象栈操作,则ActionContext.getContext.getValueStack();对Map对象进行操作,ActionContext.getContex()和ActionContext.getContext.getValueStack()都可以。
在jsp页面中,我们需要使用OGNL这种表达式语言进行操作。
2.$,%,#
${expression},是el语法。但是OGNL在struts.xml配置文件中用${}进行操作。如:
<action name="reply_*" class="replyAction" method="{1}">
<result name="addUI">/WEB-INF/jsp/replyAction/addUI.jsp</result>
<result name="toTopicShow" type="redirectAction">topic_show?id=${topicId}</result>
</action>
在jsp页面中,%{expression} 只能用在struts2标签的属性中,% 可将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用。这一点明显没有EL表达式方便,EL表达式可以单独使用。
<s:a action="user_editUI?id=%{id}">修改</s:a>
<s:a action="forum_show?id=%{#topic.forum.id}">${topic.forum.name}</s:a>
<s:property value="%{id in privilegeIds ? 'checked' : ''}"/>
#+对象的名称访问Context(Map)对象。如下:
<s:iterator value="#application.topPrivilegeList"></s:iterator>
<s:iterator value="recordList" status="status"> </s:iterator>
这两个对比一个主要是加不加#,很好理解,加了#说明是在Map中取得值,当什么符号都不写的情况下,会默认先从对象栈中查找,从栈顶开始往下找,找到则返回,若没有找到,则从map中查找key,找到则返回。
抛出一个疑问:Struts2默认使用OGNL表达式从ValueStack中取值/赋值,EL表达式默认从Page、Request、Session和 Application里顺序取值。但是,在集成了Struts2的项目中,jsp页面可以直接使用${username} 获取Action中的username属性,跟OGNL表达式获取root对象属性的使用方法一样,这是为什么呢?
struts2对默认的request进行了包装,默认会先从原request里面找,如果找不到,会从ValueStack里面找。
详细可看到这篇博客http://www.360doc.com/content/14/0512/16/16650130_376975244.shtml