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

 

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

我们经常在使用struts框架,频繁调用formaction等,但是我们可能对它内部的一些机制并不是很清楚。我们调用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页面显示出来。

测试的结果表明:方法一通过action2action1处理后,在jsp页面上查询条件是可以保存的,而方法二通过action2action1处理后,在jsp页面上查询条件并不能保存;同时我们发现,在方法一的测试中,如果在acton2中,用form.setZzlx(”10”)(在jsp页面上,“10”代表“证照类型“为“身份证”)来改变jsp页面的属性――“证照类型”原来的值(例如:原来的值为“20”,代表“军官证”,这个值是jsp页面传入的),并期待这个改变的值能在jsp页面上显示出来,其结果是失败的。结果显示的,证照类型在经过action2改变,通过action1jsp显示时,其显示值仍然为“20”,并不是我们想象中的“10”

如果我们把第二种方法增加连接参数,改为:

<a href="../action2.do?& zzlx =20&Param=11,22,33">取消疑点</a>

增加超连接的参数“zzlx =20”,查询条件的值是可以通过action2action1处理后,值得到保存,并在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>

这表明action2action1的范围为“request(scope="request"得到)。由此,我们分析如下:

1)当jsp页面调用*.do(例如:上面jsp页面调用的是:action2.do),把属性传给action2这个类(具体位置为:type="gov.chinatax.grsds.bims.web.compare.action2"),jsp把页面上的属性值(例如:证照类型的值)传递给request暂时保存(为什么是request?从struts-config.xmlscope="request"获得);

2)当程序执行到action2时,生成一个 formrequest把从jsp中获取的属性值放入form中,这样action2就可以通过form .get×××()来调用jsp页面的属性值了。当action2处理完成,转入另一个action――action1时,action2所对应的form也将消失,新的action――action1开始生成一个新的formrequest 再把从jsp中获取的值放入这个新生成的form中。我们用form.setZzlx(”10”)来试图影响action1所对应的form是不能奏效的。因为每个action都要生成一个新的formaction2生成的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.xmlscope="××× "中获得,你可能有所怀疑,不要怕,可以看看struts-config.xml中“登录页面”的action的设置?是不是scope="session"?这就表明,它的生命周期为整个session的周期,所以登录页面设置的参数值将会在连接的整个生命周期内存在。

上面说action不能通过form.set×××()传值给request,如果我们坚持通过actionrequest传值怎么办?在action中调用request.setAttribute( )函数来实现吧。

3.结论

根据以上分析,我们可以得出使用struts框架的几点结论:

1jsp调用actionaction调用jsp都是通过在struts-config.xml中设定的对应action的权限范围进行的,例如上面我们设定为request,则放入request中进行;

2Form在两个action直接转换时,form是要重新生成的,两个action中对应的form值并不能直接传递;

3)试图在action中通过设定form中属性的值,进而来影响jsp传入的属性值,如果这个action还需要再调用一个action,而不是之际调用jsp,那么这中方法将是徒劳的,因为如果action不与jsp相互调用,通过orm set×××()方法时不能把值传递给action的权限范围(例如:request)的;

4jsp页面的属性值,通过submit()提交来调用action和直接用超连接来调用action,其结果是不同的。利用submit()是可以把jsp页面的属性值传给action的,而超连接则不能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章