Java Study Center |
|
|||
日歷
統(tǒng)計(jì)
導(dǎo)航常用鏈接留言簿(1)隨筆檔案(40)文章檔案(3)搜索最新評論
閱讀排行榜評論排行榜 |
很久沒有更新BLOG了,前一段時間公司的項(xiàng)目比較忙,另外我還和一位出版社的朋友談寫書的事情,所以一直沒有時間,完成《Struts 2與AJAX》。后來寫書的事情吹了,趁今天有點(diǎn)空閑就把它完成。 在大家看這部分文章之前,我想對于寫書的事情說兩句,或者應(yīng)該叫發(fā)牢騷才對。通過這次寫書失敗的經(jīng)歷,我明白為什么國內(nèi)的IT書籍多數(shù)是濫于充數(shù)、粗制濫造、缺乏經(jīng)典。其實(shí)說白了就是一個“錢”字作怪。為了市場,很多編輯可能會“建議”你去“抄考”一些國內(nèi)相對暢銷的同類書籍,例如寫Struts就一定要按所謂的MVC進(jìn)行目錄分類,美其名曰“容易入門”。我認(rèn)為“MVC”的概念雖然重要,但對初學(xué)者而言,需要對編程有一定的了解才容易明白此概念。另外,為了“實(shí)用”,不惜使用相同的技術(shù)重復(fù)編寫不同的范例。可能是我不太了解讀者的心理吧。 言歸正傳,在上兩部分的《Struts 2與AJAX》中我介紹了Struts 2與DOJO結(jié)合實(shí)現(xiàn)AJAX的知識,本文將介紹在Struts 2中使用DWR實(shí)現(xiàn)AJAX表單校驗(yàn)。 什么是DWRDWR(Direct Web Remoting)是在Java EE中較流行的AJAX框架,它的最大優(yōu)勢就是可以像使用本地的Javascript函數(shù)一樣,調(diào)用服務(wù)器上的Java方法。如下圖所示:
其實(shí)DWR原理也不復(fù)雜,它先在web.xml中配置一個Servlet,映射到特定的路徑(通常是%CONTEXT_PATH%/dwr/*)。這個Servlet的作用就是初始化要暴露給Javascript調(diào)用的Java類(通過dwr.xml進(jìn)行配置),并生成相應(yīng)的代理的Javascript類代碼。在XHR請求到來的時候,Servlet負(fù)責(zé)將請求的參數(shù)變成對應(yīng)的Java對象,并以其為參數(shù)調(diào)用目標(biāo)Java方法,并將返回值轉(zhuǎn)化為Javascript代碼。詳情請參考:http://getahead.ltd.uk/dwr/ Struts 2與DWR在Struts 2.0.x中使用DWR實(shí)現(xiàn)AJAX表單校驗(yàn)。在大家掌握了DWR的原理后,下面我想詳細(xì)介紹一下實(shí)現(xiàn)的步驟。 首先,到以下站點(diǎn)https://dwr.dev.java.net/files/documents/2427/47455/dwr.jar下載DWR的1.1.4版本的JAR包。需要注意的是,DWR雖然已經(jīng)發(fā)布2.0版本,但它與1.1.4有很大的區(qū)別,所以請大家不要使用2.0版本,否則會出現(xiàn)異常的; 接著,新建WEB工程,將下圖所示的JAR包加入到工程的“Build Path”中;
接下來,配置web.xml文件,內(nèi)容如下: <?xml version="1.0" encoding="UTF-8"?>
清單1 WebContent/WEB-INF/web.xml
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Struts 2 AJAX Part 3</display-name> <filter> <filter-name>struts-cleanup</filter-name> <filter-class> org.apache.struts2.dispatcher.ActionContextCleanUp </filter-class> </filter> <filter-mapping> <filter-name>struts-cleanup</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.FilterDispatcher </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 開始DWR配置 --> <servlet> <servlet-name>dwr</servlet-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dwr</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> <!-- 結(jié)束DWR配置 --> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app> 然后是DWR的配置文件: <?xml version="1.0" encoding="UTF-8"?>
清單2 WebContent/WEB-INF/dwr.xml
<!-- START SNIPPET: dwr --> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <create creator="new" javascript="validator"> <param name="class" value="org.apache.struts2.validators.DWRValidator"/> </create> <convert converter="bean" match="com.opensymphony.xwork2.ValidationAwareSupport"/> </allow> <signatures> <![CDATA[ import java.util.Map; import org.apache.struts2.validators.DWRValidator; DWRValidator.doPost(String, String, Map<String, String>); ]]> </signatures> </dwr> <!-- END SNIPPET: dwr --> 通過以上配置,我們可以將DWRValidator中的方法暴露為Javascript可以調(diào)用的遠(yuǎn)程接口。 在正確完成以上步驟之后,我們發(fā)布運(yùn)行一下應(yīng)用程序,在瀏覽器地址欄中輸入http://localhost:8080/Struts2_Ajax3/dwr/,應(yīng)該會出現(xiàn)如下頁面:
接下來,我們要開始編寫Action類了,代碼如下: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 上述代碼一目了然,相信大家已經(jīng)很熟悉了。下面,我們再來看看表單校驗(yàn)的配置代碼: <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
清單4 src/tutorial/AjaxValidation-validation.xml
<validators> <validator type="regex"> <param name="fieldName">password</param> <param name="expression"> <![CDATA[(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$]]> </param> <message>Password must be between 8 and 10 characters, contain at least one digit and one alphabetic character, and must not contain special characters</message> </validator> <field name="name"> <field-validator type="requiredstring"> <message>You must enter a name</message> </field-validator> </field> <field name="age"> <field-validator type="int"> <param name="min">18</param> <param name="max">127</param> <message>Age must be between 18 and 127</message> </field-validator> </field> </validators> 對于AjaxValidation類的name、password和age三個字段,我分別用了非空、正規(guī)表達(dá)式和范圍驗(yàn)證。正規(guī)表達(dá)式(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$的作用是保證密碼由至少包括一個數(shù)字和一個字母,且不能含有符號的長度為8到10的字符串組成。它也是所謂強(qiáng)密碼(Strong Password)的普通實(shí)現(xiàn)。 接下來的是JSP的代碼,內(nèi)容如下: <%@ page language="java" contentType="text/html; charset=utf-8"
清單5 WebContent/AjaxValidation.jsp
pageEncoding="utf-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Struts 2 AJAX - Validation</title> <s:head theme="ajax" /> </head> <body> <h2> AJAX Validation Using DWR </h2> <s:form method="post" validate="true" theme="ajax"> <s:textfield label="Name" name="name" /> <s:password label="Password" name="password" /> <s:textfield label="Age" name="age" /> <s:submit /> </s:form> </body> </html> 以上代碼也不復(fù)雜,不過需要的是注意的是除了要加入<s:head theme="ajax" />外,<s:form />也必須加入validate="true" theme="ajax"的屬性。 最后是Struts 2的配置文件,內(nèi)容如下所示: <?xml version="1.0" encoding="UTF-8"?>
清單6 src/struts.xml
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="Struts2_AJAX_DEMO" extends="struts-default"> <action name="AjaxValidation" class="tutorial.AjaxValidation"> <result name="input">AjaxValidation.jsp</result> <result>AjaxValidation.jsp</result> </action> </package> </struts> 最后發(fā)布運(yùn)應(yīng)用程序,在瀏覽器地址欄中輸入http://localhost:8080/Struts2_Ajax3/AjaxValidation!input.action出現(xiàn)如下圖所示頁面:
在文本框中輸入錯誤的值使頁面出現(xiàn)錯誤提示信息,如下圖所示:
可能有朋友會問怎么知道這是通過AJAX進(jìn)行校驗(yàn)的呢?在這里我向大家推薦一個AJAX開發(fā)必備的工具——Firebug。Firebug是Firefox的一個功能強(qiáng)大的插件,它可以準(zhǔn)確地輸出和定位Javascript的錯誤、通過直觀的方式查看HTML文檔的DOM及其樣式、所見即所得的編輯方式,更值得一贊的是它可以方便地對Javascript進(jìn)行跟蹤和調(diào)試,如果你希望這進(jìn)一步了解這個工具,請安裝Firefox 2.0以上版本,并使用它瀏覽以下網(wǎng)址http://www.getfirebug.com。 在安裝完成Firebug之后,在Firefox中打開http://localhost:8080/Struts2_Ajax3/AjaxValidation!input.action,按“F12”鍵找開Firebug窗口,如果你第一次使用Firebug,請點(diǎn)擊其窗口中的鏈接“Enable Firebug”激活插件。之后,點(diǎn)擊“Net”,并在出現(xiàn)的菜單中點(diǎn)擊選中“XHR”。然后將光標(biāo)移入文本框,再將光標(biāo)移出使文本框失去焦點(diǎn),你可以看到Firebug窗口會多出一項(xiàng)記錄,如下圖所示:
這就證明你在文本框失去焦出時,Struts 2會發(fā)送XHR請求到服務(wù)器以對該文本框值進(jìn)行校驗(yàn)。有興趣的朋友可以通過Firebug,研究XHR的請求與響應(yīng),這樣可以加深對DWR工作原理的理解。 何時使用AJAX表單校驗(yàn)雖然在Struts 2實(shí)現(xiàn)AJAX表單校驗(yàn)是一件非常簡單的事,但我建議大家不要在所有的場合都使用這個功能,原因可以分為以下幾個方面:
讀到這里,有的朋友可能會問:“那么什么時候才應(yīng)該使用AJAX表單校驗(yàn)?zāi)兀?#8221;答案其實(shí)很簡單,當(dāng)我們的校驗(yàn)在頁面加載時還不能夠確定的情況下,就應(yīng)該使用這個功能。例如,注冊用戶時,校驗(yàn)用戶名是否已經(jīng)存在;或者校驗(yàn)涉及過多的頁務(wù)邏輯等。 現(xiàn)在讓我們來改造一下上述例子,對于name我們可以使用AJAX校驗(yàn),但對于其它的字段應(yīng)該使用純Javascript的校驗(yàn)。 在tutorial.AjaxValidation類加入如下方法: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 用于模擬用戶注冊的場境,當(dāng)然在真實(shí)情況應(yīng)該在數(shù)據(jù)庫中檢查用戶是否存在。 接下來再修改JSP文件,將<s:form />里面的內(nèi)容改為如下所示代碼: <s:form method="post" validate="true" theme="ajax_xhtml">
清單8 WebContent/AjaxValidation.jsp代碼片段
<s:textfield label="Name" name="name" theme="ajax" /> <s:password label="Password" name="password" theme="xhtml" /> <s:textfield label="Age" name="age" theme="xhtml" /> <s:submit theme="xhtml" /> </s:form> 對比早前的JSP代碼,大家可以看出我將<s:form />的theme改成了“ajax_xhtml”,這個theme不是Struts 2自帶,需要自定義。另外,除了Name使用了ajax的theme之外,其它的表單標(biāo)簽的theme都為xhtml,如此一來便可以實(shí)現(xiàn)只有當(dāng)Name文本框失去焦點(diǎn)時才發(fā)生AJAX表單校驗(yàn)。 接下來,應(yīng)該是我們的自定義ajax_xhtml的theme了。在源代碼文件夾下新建包“template.ajax_xhtml”,然后在其中加入form.ftl和form-close.ftl文件,內(nèi)容分別如下: <#if parameters.validate?exists>
清單9 src/template/ajax_xhtml/form.ftl
<script type="text/javascript" src="${base}/struts/validationClient.js"></script> <script type="text/javascript" src="${base}/dwr/interface/validator.js"></script> <script type="text/javascript" src="${base}/dwr/engine.js"></script> <script type="text/javascript" src="${base}/struts/ajax/validation.js"></script> </#if> <#include "/${parameters.templateDir}/xhtml/form-validate.ftl" /> <#include "/${parameters.templateDir}/simple/form.ftl" /> <#include "/${parameters.templateDir}/xhtml/control.ftl" /> 上述的文件與xhtml theme中的form.ftl文件相似,我只是加入了AJAX表單校驗(yàn)所用的Javascript庫,以便theme為ajax的表單標(biāo)簽使用。 <#include "/${parameters.templateDir}/xhtml/control-close.ftl" />
清單10 src/template/ajax_xhtml/form-close.ftl
<#include "/${parameters.templateDir}/simple/form-close.ftl" /> <#include "/${parameters.templateDir}/xhtml/form-close-validate.ftl" /> 這個文件與xhtml theme中的form-close.ftl文件相同。 最后發(fā)布運(yùn)行應(yīng)用程序,大家可以發(fā)現(xiàn)在Password與Age的校驗(yàn),只有在表單提交時才發(fā)生,而且是純Javascript的校驗(yàn)。不過,以上代碼還不是很完善,在行為上有些BUG。 總結(jié)Struts 2相比一些其它的框架,在實(shí)現(xiàn)AJAX方面的確簡單很多。更激動人心的是Struts 2的標(biāo)簽庫支持基于模板的輸出,使得開發(fā)者可以跟據(jù)自身的需要方便地改變標(biāo)簽的行為。 在將要發(fā)布的Struts 2.1版本中,AJAX表單校驗(yàn)將不再使用DWR,統(tǒng)一使用DOJO實(shí)現(xiàn),詳情請參考:http://struts.apache.org/2.0.9/docs/ajax-validation.html。 |
![]() |
|
Copyright © 綠茶_鄭州 | Powered by: 博客園 模板提供:滬江博客 |