您的位置:首页 > 编程语言 > Java开发

Struts框架内部的值调用机制的研究

2007-08-18 23:12 447 查看

Struts框架内部的值调用机制的研究

我们经常在使用struts框架,频繁调用form、action等,但是我们可能对它内部的一些机制并不是很清楚。我们调用struts框架的流程一般为:jsp把页面上的值传给form,再传递给action处理,然后把处理结果返回给jsp显示。在这个过程中, jsp页面所定义的值是如何传递的?form的生命周期又是怎么样的?我们并没有深入研究,而一些问题也就由此产生。
下面针对我们在应用struts中,所遇到的这些问题,以及验证后的结果现象,对struts内部的值调用机制进行详细说明和解释,希望有助于以后struts框架的使用。

1.出现的问题:

在项目中使用struts中,我们发现如下问题:struts框架下的值传递,form的值生命周期并不是我们原来想象的那么简单,具体现象如下:
有一个jsp页面,如下图所示:

页面上有查询和显示两部分操作功能,整个页面的在struts框架下分为几个部分:一个jsp(如图所示);一个form(与jsp中的元素相对应);为了便于逻辑处理,设定两个action(共用前面的form),一个action(命名为action1),逻辑处理为处理查询操作,并把结果显示于jsp页面上,另一个action(命名为action2),逻辑处理为执行“取消疑点”操作,并调用到action1(由action1重新执行查询逻辑后,把结果显示于jsp页面)。需要注意的是,这里是action2调用action1,然后再由action1把结果返回到jsp页面上,action2并不直接调用jsp页面。
在jsp页面,为实现“取消疑点”功能,目前采用两种实现方法,
1)jsp页面上,通过超连接,调用js函数来实现“取消”功能,形式如下:

<a href="javascript: goDetail('../action2.do?Param=11,22,33’);">取消疑点</a>

Jsp页面上的goDetail()函数实现为:

<script language="javascript">
<!--
function goDetail (str)
{
if(confirm("是否确定要取消这条记录?"))
{
url = str;
form = document.form;
form.action=url;
form.submit();
}
2) jsp页面上,通过超连接,不调用js函数直接实现“取消”功能,形式如下:
<a href="../action2.do?&Param=11,22,33">取消疑点</a>
在以上两种实现方式下,看起来实现“取消”功能是一样的:通过action2执行“取消”操作,然后通过action1把处理以后的结果显示在jsp上。对于实现“取消”功能,以上两种实现方法都可以实现,但是我们还要实现的附加功能之一是:jsp页面上的查询条件,例如:证照类型(zzlx)等,通过action2、 action1的处理之后,值依然能保存,并在jsp页面显示出来。
测试的结果表明:方法一通过action2、action1处理后,在jsp页面上查询条件是可以保存的,而方法二通过action2、action1处理后,在jsp页面上查询条件并不能保存;同时我们发现,在方法一的测试中,如果在acton2中,用form.setZzlx(”10”)(在jsp页面上,“10”代表“证照类型“为“身份证”)来改变jsp页面的属性――“证照类型”原来的值(例如:原来的值为“20”,代表“军官证”,这个值是jsp页面传入的),并期待这个改变的值能在jsp页面上显示出来,其结果是失败的。结果显示的,证照类型在经过action2改变,通过action1在jsp显示时,其显示值仍然为“20”,并不是我们想象中的“10”。
如果我们把第二种方法增加连接参数,改为:
<a href="../action2.do?& zzlx =20&Param=11,22,33">取消疑点</a>
增加超连接的参数“zzlx =20”,查询条件的值是可以通过action2、action1处理后,值得到保存,并在jsp页面上显示出来。

2.问题的分析:

根据以上的现象,我们对struts-config.xml中的action权限范围发生了兴趣,经过查找,其权限范围struts-config.xml中表现如下:
<action-mappings>
<action name="form" type="gov.chinatax.grsds.bims.web.compare.action1" scope="request" path="/action1">
<forward name="failure" path="error"/>
<forward name="success" path="/compare/agent_difference_biggish.jsp" />
</action>
<action name="form" type="gov.chinatax.grsds.bims.web.compare.action2" scope="request" path="/action2">
<forward name="failure" path="error"/>
<forward name="success" path="/compare/agent_difference_biggish.jsp" />
</action>
</action-mappings>
这表明action2、action1的范围为“request”(从scope="request"得到)。由此,我们分析如下:
1)当jsp页面调用*.do(例如:上面jsp页面调用的是:action2.do),把属性传给action2这个类(具体位置为:type="gov.chinatax.grsds.bims.web.compare.action2"),jsp把页面上的属性值(例如:证照类型的值)传递给request暂时保存(为什么是request?从struts-config.xml中scope="request"获得);
2)当程序执行到action2时,生成一个 form,request把从jsp中获取的属性值放入form中,这样action2就可以通过form .get×××()来调用jsp页面的属性值了。当action2处理完成,转入另一个action――action1时,action2所对应的form也将消失,新的action――action1开始生成一个新的form,request 再把从jsp中获取的值放入这个新生成的form中。我们用form.setZzlx(”10”)来试图影响action1所对应的form是不能奏效的。因为每个action都要生成一个新的form,action2生成的form只存在于action2的周期范围内,action2结束,form中的值随同form一起消失了,同时,在两个action之间调用时,form set×××()并不能把值由form传给request。因此在调用action1时,action2的值并不能传入action1对应的form,所以也就不能由action1传给jsp,在页面上也不能显示出来;
3)当action1调用jsp时,form中的值通过request传给jsp页面,这时候,用form.setZzlx(”10”)来改变条件的值,是可以在页面上显示的;
至于为什么jsp上的第一种方法是可以把属性值传过去的,而第二中方法为什么必须要增加超连接的参数“zzlx =20”,才能把这个条件参数传过去。原因也不难理解,看方法一与方法二有什么差别?细心的各位已经发现区别了吧?对了,就是这个:第一个是用form.submit()提交,调用action的,而第二个是直接用超连接调用的。如果用submit()提交,jsp页面上的所有值,都会放入request中,传入action所对应的form中的;而直接用超连接调用,并不经过submit(),这样,jsp页面上的值并没有任何渠道传入request,除非,增加超连接的参数“zzlx =20”,让request有渠道获得zzlx参数的值。
权限范围是不是真的从struts-config.xml中scope="××× "中获得,你可能有所怀疑,不要怕,可以看看struts-config.xml中“登录页面”的action的设置?是不是scope="session"?这就表明,它的生命周期为整个session的周期,所以登录页面设置的参数值将会在连接的整个生命周期内存在。
上面说action不能通过form.set×××()传值给request,如果我们坚持通过action给request传值怎么办?在action中调用request.setAttribute( )函数来实现吧。

3.结论

根据以上分析,我们可以得出使用struts框架的几点结论:
1)jsp调用action和action调用jsp都是通过在struts-config.xml中设定的对应action的权限范围进行的,例如上面我们设定为request,则放入request中进行;
2)Form在两个action直接转换时,form是要重新生成的,两个action中对应的form值并不能直接传递;
3)试图在action中通过设定form中属性的值,进而来影响jsp传入的属性值,如果这个action还需要再调用一个action,而不是之际调用jsp,那么这中方法将是徒劳的,因为如果action不与jsp相互调用,通过orm set×××()方法时不能把值传递给action的权限范围(例如:request)的;
4)jsp页面的属性值,通过submit()提交来调用action和直接用超连接来调用action,其结果是不同的。利用submit()是可以把jsp页面的属性值传给action的,而超连接则不能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: