| 使用AJAX的Struts驗(yàn)證框架 --實(shí)時(shí)數(shù)據(jù)驗(yàn)證是AJAX技術(shù)的一大優(yōu)勢 
  實(shí)時(shí)數(shù)據(jù)驗(yàn)證是AJAX技術(shù)的一大優(yōu)勢之一。通過應(yīng)用此技術(shù),struts驗(yàn)證框架將增強(qiáng)struts MVC,并使Web應(yīng)用程序更接近于桌面應(yīng)用程序。 此驗(yàn)證框架用于驗(yàn)證字段。有許多在Web應(yīng)用程序上進(jìn)行驗(yàn)證的方法。這些方法可分為兩類:服務(wù)器端方法和客戶端方法。Struts驗(yàn)證框架是面向基于Java的Web應(yīng)用環(huán)境的最佳框架之一。它能夠配置應(yīng)用程序,方法是使用服務(wù)器端驗(yàn)證和錯(cuò)誤消息,此錯(cuò)誤消息在處理請(qǐng)求時(shí)呈現(xiàn)在調(diào)用的驗(yàn)證流程上,它還能夠進(jìn)行客戶端驗(yàn)證,方法是使用請(qǐng)求頁面上呈現(xiàn)的JavaScript。 AJAX是一種JavaScript技術(shù),它能夠異步呼叫服務(wù)器并獲取XML文檔,這類文檔最近非常流行。其用途之一就是實(shí)時(shí)數(shù)據(jù)驗(yàn)證。 本文關(guān)注使用AJAX增強(qiáng)現(xiàn)有struts驗(yàn)證框架。必須開發(fā)幾個(gè)組件(例如控制器),以選擇驗(yàn)證框架,并呈現(xiàn)特定格式的消息(用于客戶端)和標(biāo)簽庫(處理錯(cuò)誤消息呈現(xiàn))。 必要條件需要一個(gè)具有Eclipse和Tomcat應(yīng)用服務(wù)器的Windows系統(tǒng)。請(qǐng)確定已在操作系統(tǒng)中注冊(cè)了MSXML 3.0 ActiveX對(duì)象。還需要Struts庫(http://struts.)和JDOM庫(www.),以用于XML開發(fā)(參見圖1和圖2)。 
 
 服務(wù)器端場景StrustsActionServlet我們必須擴(kuò)展來自org.apache.struts.action.ActionServlet的類,以獲得servletMapping變量,此變量存儲(chǔ)關(guān)于如何針對(duì)動(dòng)作類將該擴(kuò)展格式化為瀏覽器地址形式的動(dòng)作路徑的信息。當(dāng)添加代碼時(shí),我們必須將web.xml配置為應(yīng)用服務(wù)器的Web應(yīng)用程序描述符。 web.xml配置如下:   ...
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>net.sf.struts.servlet.StrutsActionServlet</servlet-class>
...
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
...
StrutsActionServlet Java代碼如下:
public class StrutsActionServlet extends the ActionServlet.
{
public String getServletMapping() {
return this.servletMapping;
}
}
AjaxValidationRequestProcessor要在第一步中支持現(xiàn)有Struts框架,我們必須擴(kuò)展來自Struts軟件包的RequestProcessor。我們必須定制化此請(qǐng)求處理器,因?yàn)槲覀儽仨毰袆e將如何進(jìn)行驗(yàn)證(通過使用現(xiàn)有Struts框架,還是利用AJAX概念),還因?yàn)槲覀儗⒃诜?wù)器和客戶端之間制訂一個(gè)有關(guān)如何解釋消息的契約。在消息呈現(xiàn)方面,我們將使用XML格式,這是一種很好的媒體消息傳遞格式。我們將應(yīng)用的XML格式的定義是: XML Format XML Format <?xml version="1.0" encoding="UTF-8"?> <message> <identity name=messageAreaId> <description> MessageValue </description> </identity> </message> 描述
 首先我們需要在繼續(xù)流程映射之前,從Web描述符獲得servlet映射配置。調(diào)用此流程后,應(yīng)用程序?qū)?zhǔn)備表單實(shí)例,此實(shí)例繼承自AjaxForm類。這一處理管理AJAX驗(yàn)證,并且應(yīng)進(jìn)行檢查以確定來自客戶端的請(qǐng)求沒有使用struts驗(yàn)證框架。其他在請(qǐng)求過程中執(zhí)行的流程是流程填充(用于收集客戶端發(fā)送到動(dòng)作表單的信息)和流程驗(yàn)證(通過使用現(xiàn)有Struts驗(yàn)證框架中已經(jīng)存在于AjaxValidationRequestProcessor的父類TilesRequestProcessor中的方法)。 來自TilesRequestProcessor的驗(yàn)證流程將調(diào)用所有基于struts驗(yàn)證框架的驗(yàn)證,并將動(dòng)作錯(cuò)誤存儲(chǔ)到請(qǐng)求。我們需要仔細(xì)分析動(dòng)作錯(cuò)誤,并生成XML消息驗(yàn)證,此驗(yàn)證將被發(fā)送到客戶端。因?yàn)槲覀兿M闹С烛?yàn)證的行為方式,所以驗(yàn)證流程應(yīng)檢查所用的驗(yàn)證框架的指示器(參見圖3)。 
 使用JDOM作為處理引擎,生成XML消息。如圖4所示,如果流程驗(yàn)證被調(diào)用,且驗(yàn)證框架的條件等同于AJAX驗(yàn)證框架,則流程將繼續(xù)填充錯(cuò)誤消息并構(gòu)建XML消息驗(yàn)證。 
 ErrorMessageHandler該類處理XML消息生成器的功能。此Java類將構(gòu)建基于identity和description屬性的XML消息。調(diào)用方調(diào)用了buildXMLMessage之后,它將準(zhǔn)備文檔并設(shè)置XML消息的根元素。此類還具有一個(gè)addNextXMLMessage函數(shù),以將更多驗(yàn)證消息添加到XML(參見清單1)。 清單1   ...
public void buildXMLMessage() throws ParserConfigurationException {
// initiate document builder to prepare the media of XML Message
this.rootElement = new Element(CONSTANT_MESSAGE);
addNextXMLMessage();
}
...
public void addNextXMLMessage() throws ParserConfigurationException {
// creating the xml message based on format above
Element identityElement = new Element(CONSTANT_IDENTITY);
identityElement.setAttribute(CONSTANT_NAME, this.identity);
Element descriptionElement = new  Element(CONSTANT_DESCRIPTION);
descriptionElement.addContent(this.description);
identityElement.addContent(descriptionElement);
rootElement.addContent(identityElement);
}
此流程方法將響應(yīng)的內(nèi)容類型設(shè)置為“text/xml”,并將XML消息作為字符串發(fā)送。AjaxValidationRequestProcessor代碼上的流程函數(shù)如清單2所示。 清單2   public void process(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException
{
if ( request.getParameter(CONSTANT_VALIDATION_FRAMEWORK_ARG) != null )
{
...
this.processValidate(req, resp, form, mapping);
response.setContentType(CONSTANT_XML_CONTENT_TYPE);
response.getWriter().write(sbXMLMessage.toString());
response.flushBuffer();
}
} else
{
super.process(req, resp);
}
}
processValidation方法將填充動(dòng)作錯(cuò)誤,并基于面向客戶端的XML格式契約構(gòu)建消息。AjaxValidationRequestProcessor代碼上的processValidation函數(shù)如下所示: ... ActionErrors errors = (ActionErrors) request.getAttribute(Globals.ERROR_KEY); Locale locale = (Locale) request.getAttribute(Globals.LOCALE_KEY); generateXMLMessage(errors, identity, locale, sbXMLMessage); ... 客戶端場景構(gòu)建標(biāo)簽庫組件
 配置標(biāo)簽庫定義開發(fā)出標(biāo)簽庫組件之后,我們需要配置清單3中顯示的標(biāo)簽庫tld文件。 清單3 <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>ajaxLib</shortname> <tag> <name>library</name> <tagclass>net.sf.ajax.taglib.AjaxJavaScriptLibrary </tagclass> <bodycontent>JSP</bodycontent> </tag> <tag> <name>error</name> <tagclass>net.sf.ajax.taglib.AjaxErrorHtmlRender </tagclass> <bodycontent>JSP</bodycontent> <attribute> <name>property</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>event</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib> 構(gòu)建JSP和Struts配置要模擬驗(yàn)證處理的結(jié)果,我們首先需要構(gòu)建呈現(xiàn)層,方法是合并我們已經(jīng)構(gòu)建的標(biāo)簽庫。在此例中,我試圖給出一個(gè)示例驗(yàn)證(通過使用來自Struts的驗(yàn)證規(guī)則組件)以及來自表單本身的驗(yàn)證。準(zhǔn)備五個(gè)JSP頁面下的文本框。第一個(gè)到第四個(gè)文本框使用驗(yàn)證規(guī)則配置,第五個(gè)文本框使用來自動(dòng)作表單的驗(yàn)證流程。除此之外,我們還需要一個(gè)提交按鈕,以在提交表單后模擬它,現(xiàn)有的struts驗(yàn)證仍在沒有AJAX的情況下工作。用戶界面外觀如圖5所示。 
 構(gòu)建動(dòng)作和動(dòng)作表單為獲得Struts動(dòng)作,我們轉(zhuǎn)到已經(jīng)構(gòu)建的JSP。此動(dòng)作代碼如下所示:   public ActionForward execute(...) {
return mapping.findForward("success");
}如果輸入為空,則此動(dòng)作表單代碼將驗(yàn)證requiredText屬性。請(qǐng)記住,要從AjaxForm類擴(kuò)展此表單。動(dòng)作表單的驗(yàn)證方法如下所示:   public ActionErrors validate(...) {
ActionErrors errors = new ActionErrors();
if (StringUtils.isEmpty(this.requiredText)) {
errors.add("requiredText", new ActionError("error.required.input"));
}
request.setAttribute(Globals.ERROR_KEY, errors);
}
應(yīng)用Struts驗(yàn)證規(guī)則配置Struts驗(yàn)證規(guī)則(例如最小長度、最大長度、電子郵件和模式文本)將應(yīng)用于客戶端的輸入對(duì)象,且配置與清單4類似。 清單4   <field property="paternText"
depends="required,mask">
<arg0 key="label.paternText"/>
<var>
<var-name>mask</var-name>
<var-value>^[0-9]{3}-[0-9]{2}$</var-value>
</var>
</field>
<field property="minLength"
depends="minlength">
<arg0 key="label.minLength"/>
<arg1 key="${var:minlength}" resource="false"/>
<var>
<var-name>minlength</var-name>
<var-value>5</var-value>
</var>
</field>
<field property="maxLength"
depends="maxlength">
<arg0 key="label.maxLength"/>
<arg1 key="${var:maxlength}" resource="false"/>
<var>
<var-name>maxlength</var-name>
<var-value>5</var-value>
</var>
</field>
<field property="email"
depends="email">
<arg0 key="label.email"/>
</field>
驗(yàn)證處理流首先客戶端會(huì)初始化XMLHTTP組件以執(zhí)行到服務(wù)器的請(qǐng)求,然后在用戶觸發(fā)器開始構(gòu)建時(shí),URL參數(shù)將被發(fā)送到服務(wù)器。在完成構(gòu)建參數(shù)后,客戶端會(huì)連接oneadystatechange XMLHTTP事件,以偵聽來自服務(wù)器端的響應(yīng)。收到響應(yīng)后,客戶端會(huì)開始分析XML驗(yàn)證消息,并將消息放置到正確的區(qū)域(參見圖6)。 
 如果請(qǐng)求被服務(wù)器接受,則服務(wù)器會(huì)開始檢查AJAX驗(yàn)證條件的參數(shù),并處理驗(yàn)證。完成之后,將從生成的錯(cuò)誤對(duì)象過濾出與用戶輸入對(duì)象相關(guān)的特定錯(cuò)誤。在過濾流程完成之后,將生成XML消息,并發(fā)送回客戶端(參見圖7)。 
 結(jié)束語在本文中,我們構(gòu)建了一個(gè)控制器,它能夠接收來自客戶端的異步請(qǐng)求,并合并struts驗(yàn)證流程以產(chǎn)生動(dòng)作錯(cuò)誤對(duì)象。在產(chǎn)生錯(cuò)誤對(duì)象并生成作為應(yīng)答返回客戶端以指示錯(cuò)誤消息的XML消息之后,將對(duì)被驗(yàn)證的特定輸入對(duì)象進(jìn)行過濾(參見圖8和圖9)。 
 
 | 
|  |