Struts源码研究 - html:Cancel标签应用注意事项

来源:互联网 发布:网络成端是什么意思 编辑:程序博客网 时间:2024/05/17 06:12
Struts里的html:Cancel标签是在Form中经常运用的一个标签,主要功能就是cancel当前Form,一般写法如下:
  1. <html:cancel>
  2. <bean:message key="createuser.cancelbutton"/>
  3. </html:cancel>

这个标签将生成如下的HTML代码:
<input type="submit" name="org.apache.struts.taglib.html.CANCEL" value="返回" >
bCancel=true是一段javascript,bCancel是在使用Struts的Validator时,Struts自动为我们加的一段Javascript代码里的一个变量
这段Javascript简略摘要如下:

  1. <script type="text/javascript" language="Javascript1.1"
  2. <!-- Begin 
  3. var bCancel = false
  4. function validateCreateUserForm(form) { 
  5. if (bCancel) 
  6. return true
  7. else 
  8. return validateMaxLength(form) && validateRequired(form) && validateMinLength(form); 
  9. 。。。以下省略
由上可以看到,这个bCancel=true时,Javascript将自动将表单提交(return true),也就是说,如果我们在后台Action的代码里
没有对这个Cancel动作写特定代码的话,这个Cancel标签产生的效果和submit按钮产生的动作完全一致!!(因为这个按钮的
type也等于submit)
这一点需要非常的注意!所以,一般来说,我们在Action类的execute方法里面会加上如下的一段代码来处理这个Cancel动作:

  1. // Was this transaction cancelled?
  2. if (isCancelled(request)) {
  3. return (mapping.findForward("createusersuccess"));
  4. }
有了以上的代码,Cancel动作就有了相应的处理代码,转到相关的页面了。
本来事情已经解决,但本着对Struts源码研究的精神,我们还需要对以上代码研究一下
OK,让我们来看一下isCancelled这个方法在什么地方被定义了,内容是什么?
首先发现,这个方法被定义在Action类里面,代码如下:

  1. /**
  2. * <p>Returns <code>true</code> if the current form's cancel button was
  3. * pressed. This method will check if the <code>Globals.CANCEL_KEY</code>
  4. * request attribute has been set, which normally occurs if the cancel
  5. * button generated by <strong>CancelTag</strong> was pressed by the user
  6. * in the current request. If <code>true</code>, validation performed
  7. * by an <strong>ActionForm</strong>'s <code>validate()</code> method
  8. * will have been skipped by the controller servlet.</p>
  9. *
  10. * @param request The servlet request we are processing
  11. * @see org.apache.struts.taglib.html.CancelTag
  12. */
  13. protected boolean isCancelled(HttpServletRequest request) {
  14. return (request.getAttribute(Globals.CANCEL_KEY) != null);
  15. }
哦,原来是在request对象中查找Globals.CANCEL_KEY这个key值是否绑定了一个对象,如果是,那么就代表按下Cancel按钮后,
Struts会在request对象中绑定一个对象,并以这个key值来命名
那Struts是在什么地方绑定了这个对象呢?很自然的,让我们从头找起
从ActionServlet的process方法开始找起,历经多次方法调用,终于找到了根源,原来是在RequestProcessor.java中,代码如下:
  1. /**
  2. * <p>Process an <code>HttpServletRequest</code> and create the
  3. * corresponding <code>HttpServletResponse</code>.</p>
  4. *
  5. * @param request The servlet request we are processing
  6. * @param response The servlet response we are creating
  7. *
  8. * @exception IOException if an input/output error occurs
  9. * @exception ServletException if a processing exception occurs
  10. */
  11. public void process(HttpServletRequest request,
  12. HttpServletResponse response)
  13. throws IOException, ServletException {
  14. //。。。省略代码若干
  15. // Process any ActionForm bean related to this request
  16. ActionForm form = processActionForm(request, response, mapping);
  17. //答案就在这个processPopulate方法中
  18. processPopulate(request, response, form, mapping);
  19. if (!processValidate(request, response, form, mapping)) {
  20. return;
  21. }
  22. /**
  23. * Populate the properties of the specified ActionForm instance from
  24. * the request parameters included with this request. In addition,
  25. * request attribute <code>Globals.CANCEL_KEY</code> will be set if
  26. * the request was submitted with a button created by
  27. * <code>CancelTag</code>.
  28. *
  29. * @param request The servlet request we are processing
  30. * @param response The servlet response we are creating
  31. * @param form The ActionForm instance we are populating
  32. * @param mapping The ActionMapping we are using
  33. *
  34. * @exception ServletException if thrown by RequestUtils.populate()
  35. */
  36. protected void processPopulate(HttpServletRequest request,
  37. HttpServletResponse response,
  38. ActionForm form,
  39. ActionMapping mapping)
  40. throws ServletException {
  41. if (form == null) {
  42. return;
  43. }
  44. // Populate the bean properties of this ActionForm instance
  45. if (log.isDebugEnabled()) {
  46. log.debug(" Populating bean properties from this request");
  47. }
  48. form.setServlet(this.servlet);
  49. form.reset(mapping, request);
  50. if (mapping.getMultipartClass() != null) {
  51. request.setAttribute(Globals.MULTIPART_KEY,
  52. mapping.getMultipartClass());
  53. }
  54. RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix(),
  55. request);
  56. // Set the cancellation request attribute if appropriate
  57. if ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||
  58. (request.getParameter(Constants.CANCEL_PROPERTY_X) != null)) {
  59. request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);
  60. }
  61. }
OK,看最后几行代码,Struts从request中取得Constants.CANCEL_PROPERTY这个参数,如果这个参数不为空,那么他就将
TRUE这个对象以Globals.CANCEL_KEY为key值,放到了request对象中
至于这个Constants.CANCEL_PROPERTY这个值是什么,现在都可以猜到了,显然就是html:Cancel这个标签生成的HTML代码
中,Cancel这个按钮的名称嘛!查了一下,果然是:

  1. <input type="submit" name="org.apache.struts.taglib.html.CANCEL" value="返回" >
而Constants.CANCEL_PROPERTY这个值就是org.apache.struts.taglib.html.CANCEL

至此,真相大白,看来以后使用html:Cancel这个标签要小心了 :)
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 支付宝手机冲错怎么办 手机停用了支付宝充值码怎么办 苹果手机桌面上找不到支付宝怎么办 苹果手机支付宝找不到了怎么办 微信上充话费没到账怎么办 冲q币不到账怎么办 支付宝冲话费没到帐怎么办 qq实名认证没有银行卡怎么办 微信零钱限额没有银行卡怎么办 qq钱包忘记支付密码怎么办 零钱包密码忘了怎么办 关爱通密码知道卡号忘了怎么办 卡号的密码忘了怎么办 银行卡号密码忘了怎么办 微信超出单月支付限额怎么办 行李箱三位数密码忘记了怎么办 手机忘记4位数密码怎么办 win7登入密码忘记了怎么办 电脑登入密码忘记了怎么办 电脑忘记登入密码怎么办 qq钱包支付密码忘了怎么办 财付通转走我卡里的钱怎么办 银行卡资金通过财付通被盗怎么办 社保卡忘了密码怎么办 医保卡忘了密码怎么办 手机qq红包忘记支付密码怎么办 微信红包忘记支付密码怎么办 充点话费充错了怎么办 qq转账记录删除了怎么办 qq转账记录删了怎么办 qq怎么办?q币转给微信 q币送不了别人怎么办 新qq号忘记了怎么办 手机qq登不上去怎么办 qq的账号忘了怎么办 微信红包密码输错锁了怎么办 陌陌钱包异常钱怎么办 对公账户转错了怎么办 微信零钱转账限额怎么办 微信红包充错话费怎么办 qq支付20万限额怎么办