| 
 | 
 
 
发表于 2007-4-2 16:47:59
|
显示全部楼层
 
 
 
暂时没人回答我就回答一下,首先声明下,下面知识是转贴,非原创 
 
Struts里的html:Cancel标签是在Form中经常运用的一个标签,主要功能就是cancel当前Form,一般写法如下: 
 
======================================================= 
<html:cancel> 
<bean:message key="createuser.cancelbutton"/> 
</html:cancel> 
======================================================= 
 
这个标签将生成如下的HTML代码: 
<input type="submit" name="org.apache.struts.taglib.html.CANCEL" value="返回" onclick="bCancel=true;"> 
bCancel=true是一段javascript,bCancel是在使用Struts的Validator时,Struts自动为我们加的一段Javascript代码里的一个变量 
这段Javascript简略摘要如下: 
 
======================================================= 
<script type="text/javascript" language="Javascript1.1">  
 
<!-- Begin  
 
var bCancel = false;  
 
function validateCreateUserForm(form) {  
if (bCancel)  
return true;  
else  
return validateMaxLength(form) && validateRequired(form) && validateMinLength(form);  
}  
 
。。。以下省略 
======================================================= 
 
由上可以看到,这个bCancel=true时,Javascript将自动将表单提交(return true),也就是说,如果我们在后台Action的代码里 
没有对这个Cancel动作写特定代码的话,这个Cancel标签产生的效果和submit按钮产生的动作完全一致!!(因为这个按钮的 
type也等于submit) 
这一点需要非常的注意!所以,一般来说,我们在Action类的execute方法里面会加上如下的一段代码来处理这个Cancel动作: 
 
======================================================= 
// Was this transaction cancelled? 
if (isCancelled(request)) { 
return (mapping.findForward("createusersuccess")); 
} 
======================================================= 
 
有了以上的代码,Cancel动作就有了相应的处理代码,转到相关的页面了。 
本来事情已经解决,但本着对Struts源码研究的精神,我们还需要对以上代码研究一下 
OK,让我们来看一下isCancelled这个方法在什么地方被定义了,内容是什么? 
首先发现,这个方法被定义在Action类里面,代码如下: 
 
======================================================= 
/** 
* <p>Returns <code>true</code> if the current form's cancel button was 
* pressed. This method will check if the <code>Globals.CANCEL_KEY</code> 
* request attribute has been set, which normally occurs if the cancel 
* button generated by <strong>CancelTag</strong> was pressed by the user 
* in the current request. If <code>true</code>, validation performed 
* by an <strong>ActionForm</strong>'s <code>validate()</code> method 
* will have been skipped by the controller servlet.</p> 
* 
* @param request The servlet request we are processing 
* @see org.apache.struts.taglib.html.CancelTag 
*/ 
protected boolean isCancelled(HttpServletRequest request) { 
 
return (request.getAttribute(Globals.CANCEL_KEY) != null); 
 
} 
======================================================= 
 
哦,原来是在request对象中查找Globals.CANCEL_KEY这个key值是否绑定了一个对象,如果是,那么就代表按下Cancel按钮后, 
Struts会在request对象中绑定一个对象,并以这个key值来命名 
那Struts是在什么地方绑定了这个对象呢?很自然的,让我们从头找起 
从ActionServlet的process方法开始找起,历经多次方法调用,终于找到了根源,原来是在RequestProcessor.java中,代码如下: 
 
======================================================= 
/** 
* <p>Process an <code>HttpServletRequest</code> and create the 
* corresponding <code>HttpServletResponse</code>.</p> 
* 
* @param request The servlet request we are processing 
* @param response The servlet response we are creating 
* 
* @exception IOException if an input/output error occurs 
* @exception ServletException if a processing exception occurs 
*/ 
public void process(HttpServletRequest request, 
HttpServletResponse response) 
throws IOException, ServletException { 
 
//。。。省略代码若干 
// Process any ActionForm bean related to this request 
ActionForm form = processActionForm(request, response, mapping); 
//答案就在这个processPopulate方法中 
processPopulate(request, response, form, mapping); 
if (!processValidate(request, response, form, mapping)) { 
return; 
} 
 
/** 
* Populate the properties of the specified ActionForm instance from 
* the request parameters included with this request. In addition, 
* request attribute <code>Globals.CANCEL_KEY</code> will be set if 
* the request was submitted with a button created by 
* <code>CancelTag</code>. 
* 
* @param request The servlet request we are processing 
* @param response The servlet response we are creating 
* @param form The ActionForm instance we are populating 
* @param mapping The ActionMapping we are using 
* 
* @exception ServletException if thrown by RequestUtils.populate() 
*/ 
protected void processPopulate(HttpServletRequest request, 
HttpServletResponse response, 
ActionForm form, 
ActionMapping mapping) 
throws ServletException { 
 
if (form == null) { 
return; 
} 
 
// Populate the bean properties of this ActionForm instance 
if (log.isDebugEnabled()) { 
log.debug(" Populating bean properties from this request"); 
} 
 
form.setServlet(this.servlet); 
form.reset(mapping, request); 
 
if (mapping.getMultipartClass() != null) { 
request.setAttribute(Globals.MULTIPART_KEY, 
mapping.getMultipartClass()); 
} 
 
RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix(), 
request); 
 
// Set the cancellation request attribute if appropriate 
if ((request.getParameter(Constants.CANCEL_PROPERTY) != null) || 
(request.getParameter(Constants.CANCEL_PROPERTY_X) != null)) { 
 
request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE); 
} 
 
} 
 
======================================================= 
 
OK,看最后几行代码,Struts从request中取得Constants.CANCEL_PROPERTY这个参数,如果这个参数不为空,那么他就将 
TRUE这个对象以Globals.CANCEL_KEY为key值,放到了request对象中 
至于这个Constants.CANCEL_PROPERTY这个值是什么,现在都可以猜到了,显然就是html:Cancel这个标签生成的HTML代码 
中,Cancel这个按钮的名称嘛!查了一下,果然是: 
 
<input type="submit" name="org.apache.struts.taglib.html.CANCEL" value="返回" onclick="bCancel=true;"> 
而Constants.CANCEL_PROPERTY这个值就是org.apache.struts.taglib.html.CANCEL 
 
至此,真相大白,看来以后使用html:Cancel这个标签要小心了 :) |   
 
 
 
 |