strust小结

来源:互联网 发布:美孚一号 知乎 编辑:程序博客网 时间:2024/05/16 11:25

Strust关于值栈:

值栈的生命周期:每次请求(request)都会产生一个新的值栈(ValueStack,即值栈的生命周期和request一样,一次请求产生一个新的值栈,请求结束,值栈销毁,

值栈与action:强调一点,不是每个值栈都有(包含)action对象,当客户访问的是项目的静态资源(如jsp)的时候值栈中不包含action对象,比如2jsp页面用超链接进行相互访问的时候,可以再Strust的标签库中用dubug标签查看,如果从一个页面链接到另一个页面,即不通过action而直接访问jsp页面,其实很多人认为action和值栈是同是产生的(甚至是同一个对象)是一个错误的观点。当客户端发起一个请求的时候,首先通过拦截器(前端控制器)进行拦截,客户的每次请求都必然会通过该控制器的doFilter方法,然后为这次请求创建一个值栈(ValueStack,然后在判断该次请求的资源是jsp页面还是action。如果是jsp页面做一次简单的参数和请求对象的封装就直接通过请求(转发到jsp页面),如果是action则会创建action对象最后并把当前action对象存入到值栈中。但是不管访问的是静态资源还是action,前端控制器都会对请求的加强(重写request.getAttrbuti()方法)这就是为什么el表达是能在页面获取值栈的数据,然后把一些web组件对象如request.respons…等保存到值栈里面,所以我们如果是通过重定向或者通过超链接(不通过action而直接跳转)jsp页面的时候我们可以通过struts标签库的debug标签看到里面的栈顶数据为空,action对象为空,但是下面的请求对象,以及请求的参数和一些请求的信息是存在的。

值栈内部结构:值栈是一个复杂的数据类型里面有多个对象,主要的存储数据的对象有2个,一个是context(OgnlContext),一个是root(CompountRoot), contexts是一个Map类型主要保存的数据对象是web组件对象,通过键值对保存,struts会默认的吧paramters,request,session,application,attr,等和请求有关的参数对象压入到该对象中,当然也可以通过该对象的put方法以键值对的方式向里面压入数据(对象)。root是一个ArrayList类型,该对象主要用户保存相应个用户的数据,比如一个实体对象,一个集合对象(数据大部分来自数据库),主要是因为该数据在相应给页面的时候root里面的数据是放在栈顶的,栈顶数据读取方便和使用灵活,还有一点值得提一下的是action对象也是存放在该对象中的,所以action自带的属性(必须提供getter也会出现在栈顶,读取也很方便,通过该对象的setpush方法可以向该对象存入对象(数据),但不管是通过push还是set存入的数据都是在栈顶。Context除了包含请求的对象意外还包含整个root对象,通过断点调试发现root本身和context下的root是同一个对象。这些大部分结构可以再jsp页面。通过strust标签库的debug标签看到

栈顶数据:如果该action实现了ModelDriven接口那放在栈顶的数据就是该借口传入的实体对象,如果action有自带属性并且提供了getter方法那栈顶的数据就会是当前action的属性,因为在ModelDriven接口内部吧当前对象(传入对象)通过push方法吧该对象压入栈顶,而action自带的属性是在action初始化的时候(在ModelDriven之后)类似于push到栈顶,所以会替代栈顶的数据。但请求具体的某个action(方法)的时候,里面的数据无论是通过push,还是set压入的数据,都会替代原来栈顶的数据。

关于valueStack存取值:有三种方式向值栈中存值,一种是通过root对象push方法吧一个对象(字符串,数字,最后都会被转化成一个对象)压入栈顶,此时这个对象没有键与之对应,只能通过Strustproperty标签的value=””[0].top,方法去取值。第二种是通过root对象set的方式去存,set以键(名)值对的方式存入valueStack,也是存入栈顶,会替代原来数据的栈顶的位置。页面通过strust标签取值,可以通过[0].top方式去取 ,也可以通过键去取对应的值(对象)。以上两中方式的数据都是存入root(CompountRoot)对象,所以默认就在栈顶,第三种是通过context对象的put方式存,这中方式不是存在栈顶,而且必须是键值对,页面取值必须通过#键才能娶到值,在页面debug标签里面可以清楚的看到root对象的值都是存在上面的,而context的值都是存在下面的,所以取上面的不要#,取下面的都要#,strust有一个迭代标签<s:iterator>有点点特殊,主要是因为它在迭代每条数据的是,都会把当前的对象(迭代的对象肯定是一个集合)放入栈顶,迭代完毕以后会立刻吧该数据重栈顶踢出去,然后下一条数据再次进入栈顶,知道迭代完毕,更有意思的是,它除了先栈顶加入数据外,还会向下面的集合(context)里面拷贝一个对象,然后保存到里里面,所以在迭代过程中通过#对象名点属性名(该属性必须提供getter)获取值,还可以直接通过属性名,这就很验证了之前的说法,栈顶有一个对象,下面(context)也有一个对象,并且如果在迭代完毕以后再到下面放一个debug标签可以找到那个对象(集合中的最后条数据)。

<table><tr><td>编号</td><td>用户名</td><td>密码</td></tr><s:iterator var="u" value="us"><tr><td><s:property value="id"/></td><td><s:property value="#u.userName"/></td><td><s:property value="#u.password"/></td></tr></s:iterator></table>

0 0
原创粉丝点击