<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java Study Center  
    日歷
    <2008年9月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011
    統(tǒng)計(jì)
    • 隨筆 - 40
    • 文章 - 3
    • 評(píng)論 - 0
    • 引用 - 0

    導(dǎo)航

    常用鏈接

    留言簿(1)

    隨筆檔案(40)

    文章檔案(3)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

     

    很久沒(méi)有更新BLOG了,前一段時(shí)間公司的項(xiàng)目比較忙,另外我還和一位出版社的朋友談寫(xiě)書(shū)的事情,所以一直沒(méi)有時(shí)間,完成《Struts 2與AJAX》。后來(lái)寫(xiě)書(shū)的事情吹了,趁今天有點(diǎn)空閑就把它完成。

    在大家看這部分文章之前,我想對(duì)于寫(xiě)書(shū)的事情說(shuō)兩句,或者應(yīng)該叫發(fā)牢騷才對(duì)。通過(guò)這次寫(xiě)書(shū)失敗的經(jīng)歷,我明白為什么國(guó)內(nèi)的IT書(shū)籍多數(shù)是濫于充數(shù)、粗制濫造、缺乏經(jīng)典。其實(shí)說(shuō)白了就是一個(gè)“錢(qián)”字作怪。為了市場(chǎng),很多編輯可能會(huì)“建議”你去“抄考”一些國(guó)內(nèi)相對(duì)暢銷的同類書(shū)籍,例如寫(xiě)Struts就一定要按所謂的MVC進(jìn)行目錄分類,美其名曰“容易入門(mén)”。我認(rèn)為“MVC”的概念雖然重要,但對(duì)初學(xué)者而言,需要對(duì)編程有一定的了解才容易明白此概念。另外,為了“實(shí)用”,不惜使用相同的技術(shù)重復(fù)編寫(xiě)不同的范例。可能是我不太了解讀者的心理吧。

    言歸正傳,在上兩部分的《Struts 2與AJAX》中我介紹了Struts 2與DOJO結(jié)合實(shí)現(xiàn)AJAX的知識(shí),本文將介紹在Struts 2中使用DWR實(shí)現(xiàn)AJAX表單校驗(yàn)。

    什么是DWR

    DWR(Direct Web Remoting)是在Java EE中較流行的AJAX框架,它的最大優(yōu)勢(shì)就是可以像使用本地的Javascript函數(shù)一樣,調(diào)用服務(wù)器上的Java方法。如下圖所示:

    DWR工作原理
    圖1 DWR工作原理

    其實(shí)DWR原理也不復(fù)雜,它先在web.xml中配置一個(gè)Servlet,映射到特定的路徑(通常是%CONTEXT_PATH%/dwr/*)。這個(gè)Servlet的作用就是初始化要暴露給Javascript調(diào)用的Java類(通過(guò)dwr.xml進(jìn)行配置),并生成相應(yīng)的代理的Javascript類代碼。在XHR請(qǐng)求到來(lái)的時(shí)候,Servlet負(fù)責(zé)將請(qǐng)求的參數(shù)變成對(duì)應(yīng)的Java對(duì)象,并以其為參數(shù)調(diào)用目標(biāo)Java方法,并將返回值轉(zhuǎn)化為Javascript代碼。詳情請(qǐng)參考: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ū)別,所以請(qǐng)大家不要使用2.0版本,否則會(huì)出現(xiàn)異常的;

    接著,新建WEB工程,將下圖所示的JAR包加入到工程的“Build Path”中;

    依賴的JAR包
    圖2 依賴的JAR包

    接下來(lái),配置web.xml文件,內(nèi)容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <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>
       
    <!-- 開(kāi)始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>
    清單1 WebContent/WEB-INF/web.xml

    然后是DWR的配置文件:

    <?xml version="1.0" encoding="UTF-8"?>

    <!-- 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 -->
    清單2 WebContent/WEB-INF/dwr.xml

    通過(guò)以上配置,我們可以將DWRValidator中的方法暴露為Javascript可以調(diào)用的遠(yuǎn)程接口。

    在正確完成以上步驟之后,我們發(fā)布運(yùn)行一下應(yīng)用程序,在瀏覽器地址欄中輸入http://localhost:8080/Struts2_Ajax3/dwr/,應(yīng)該會(huì)出現(xiàn)如下頁(yè)面:

    DWR Servlet默認(rèn)輸出頁(yè)面
    圖3 DWR Servlet默認(rèn)輸出頁(yè)面

     接下來(lái),我們要開(kāi)始編寫(xiě)Action類了,代碼如下:

    package tutorial;

    import com.opensymphony.xwork2.ActionSupport;

    public class AjaxValidation extends ActionSupport {
       
    private static final long serialVersionUID = -7901311649275887920L;

       
    private String name;
       
    private String password;
       
    private int age;
       
       
    public int getAge() {
           
    return age;
       }

       
       
    public void setAge(int age) {
           
    this.age = age;
       }

       
       
    public String getName() {
           
    return name;
       }

       
       
    public void setName(String name) {
           
    this.name = name;
       }

       
       
    public String getPassword() {
           
    return password;
       }

       
       
    public void setPassword(String password) {
           
    this.password = password;
       }

       
       @Override
       
    public String execute() {        
           
    return SUCCESS;
       }

    }
    清單3 src/tutorial/AjaxValidation.java

    上述代碼一目了然,相信大家已經(jīng)很熟悉了。下面,我們?cè)賮?lái)看看表單校驗(yàn)的配置代碼:

    <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
    <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>
    清單4 src/tutorial/AjaxValidation-validation.xml

    對(duì)于AjaxValidation類的name、password和age三個(gè)字段,我分別用了非空、正規(guī)表達(dá)式和范圍驗(yàn)證。正規(guī)表達(dá)式(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$的作用是保證密碼由至少包括一個(gè)數(shù)字和一個(gè)字母,且不能含有符號(hào)的長(zhǎng)度為8到10的字符串組成。它也是所謂強(qiáng)密碼(Strong Password)的普通實(shí)現(xiàn)。

    接下來(lái)的是JSP的代碼,內(nèi)容如下:

    <%@ page language="java" contentType="text/html; charset=utf-8"
        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>
    清單5 WebContent/AjaxValidation.jsp

    以上代碼也不復(fù)雜,不過(guò)需要的是注意的是除了要加入<s:head theme="ajax" />外,<s:form />也必須加入validate="true" theme="ajax"的屬性。

    最后是Struts 2的配置文件,內(nèi)容如下所示:

    <?xml version="1.0" encoding="UTF-8"?>

    <!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>
    清單6 src/struts.xml

    最后發(fā)布運(yùn)應(yīng)用程序,在瀏覽器地址欄中輸入http://localhost:8080/Struts2_Ajax3/AjaxValidation!input.action出現(xiàn)如下圖所示頁(yè)面:

    AjaxValidation頁(yè)面輸出
    圖4 AjaxValidation頁(yè)面輸出

    在文本框中輸入錯(cuò)誤的值使頁(yè)面出現(xiàn)錯(cuò)誤提示信息,如下圖所示:

    AjaxValidation頁(yè)面錯(cuò)誤提示
    圖5 AjaxValidation頁(yè)面錯(cuò)誤提示

    可能有朋友會(huì)問(wèn)怎么知道這是通過(guò)AJAX進(jìn)行校驗(yàn)的呢?在這里我向大家推薦一個(gè)AJAX開(kāi)發(fā)必備的工具——Firebug。Firebug是Firefox的一個(gè)功能強(qiáng)大的插件,它可以準(zhǔn)確地輸出和定位Javascript的錯(cuò)誤、通過(guò)直觀的方式查看HTML文檔的DOM及其樣式、所見(jiàn)即所得的編輯方式,更值得一贊的是它可以方便地對(duì)Javascript進(jìn)行跟蹤和調(diào)試,如果你希望這進(jìn)一步了解這個(gè)工具,請(qǐng)安裝Firefox 2.0以上版本,并使用它瀏覽以下網(wǎng)址http://www.getfirebug.com

    在安裝完成Firebug之后,在Firefox中打開(kāi)http://localhost:8080/Struts2_Ajax3/AjaxValidation!input.action,按“F12”鍵找開(kāi)Firebug窗口,如果你第一次使用Firebug,請(qǐng)點(diǎn)擊其窗口中的鏈接“Enable Firebug”激活插件。之后,點(diǎn)擊“Net”,并在出現(xiàn)的菜單中點(diǎn)擊選中“XHR”。然后將光標(biāo)移入文本框,再將光標(biāo)移出使文本框失去焦點(diǎn),你可以看到Firebug窗口會(huì)多出一項(xiàng)記錄,如下圖所示:

    Firebug中查看XHR請(qǐng)求
    圖6 Firebug中查看XHR請(qǐng)求

    這就證明你在文本框失去焦出時(shí),Struts 2會(huì)發(fā)送XHR請(qǐng)求到服務(wù)器以對(duì)該文本框值進(jìn)行校驗(yàn)。有興趣的朋友可以通過(guò)Firebug,研究XHR的請(qǐng)求與響應(yīng),這樣可以加深對(duì)DWR工作原理的理解。

    何時(shí)使用AJAX表單校驗(yàn)

    雖然在Struts 2實(shí)現(xiàn)AJAX表單校驗(yàn)是一件非常簡(jiǎn)單的事,但我建議大家不要在所有的場(chǎng)合都使用這個(gè)功能,原因可以分為以下幾個(gè)方面:

    1. AJAX校驗(yàn)在服務(wù)器上進(jìn)行數(shù)據(jù)校驗(yàn),可能會(huì)比較耗時(shí);
    2. AJAX校驗(yàn)可能會(huì)過(guò)于頻繁,加重服務(wù)器的負(fù)載;
    3. 一些普通的校驗(yàn),只需要使用純Javascript便可以實(shí)現(xiàn)。

    讀到這里,有的朋友可能會(huì)問(wèn):“那么什么時(shí)候才應(yīng)該使用AJAX表單校驗(yàn)?zāi)兀?#8221;答案其實(shí)很簡(jiǎn)單,當(dāng)我們的校驗(yàn)在頁(yè)面加載時(shí)還不能夠確定的情況下,就應(yīng)該使用這個(gè)功能。例如,注冊(cè)用戶時(shí),校驗(yàn)用戶名是否已經(jīng)存在;或者校驗(yàn)涉及過(guò)多的頁(yè)務(wù)邏輯等。

    現(xiàn)在讓我們來(lái)改造一下上述例子,對(duì)于name我們可以使用AJAX校驗(yàn),但對(duì)于其它的字段應(yīng)該使用純Javascript的校驗(yàn)。

    在tutorial.AjaxValidation類加入如下方法:

       @Override
       
    public void validate() {
           Set
    <String> users = new HashSet<String>();
           users.add(
    "max");
           users.add(
    "scott");
           
    if(users.contains(name)) {
               addFieldError(
    "name", "The user name has been used!");
           }

       }
    清單7 src/tutorial/AjaxValidation.java代碼片段

    用于模擬用戶注冊(cè)的場(chǎng)境,當(dāng)然在真實(shí)情況應(yīng)該在數(shù)據(jù)庫(kù)中檢查用戶是否存在。

    接下來(lái)再修改JSP文件,將<s:form />里面的內(nèi)容改為如下所示代碼:

            <s:form method="post" validate="true" theme="ajax_xhtml">
               
    <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>
    清單8 WebContent/AjaxValidation.jsp代碼片段

    對(duì)比早前的JSP代碼,大家可以看出我將<s:form />的theme改成了“ajax_xhtml”,這個(gè)theme不是Struts 2自帶,需要自定義。另外,除了Name使用了ajax的theme之外,其它的表單標(biāo)簽的theme都為xhtml,如此一來(lái)便可以實(shí)現(xiàn)只有當(dāng)Name文本框失去焦點(diǎn)時(shí)才發(fā)生AJAX表單校驗(yàn)。

    接下來(lái),應(yīng)該是我們的自定義ajax_xhtml的theme了。在源代碼文件夾下新建包“template.ajax_xhtml”,然后在其中加入form.ftl和form-close.ftl文件,內(nèi)容分別如下:

    <#if parameters.validate?exists>
    <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" />
    清單9 src/template/ajax_xhtml/form.ftl

    上述的文件與xhtml theme中的form.ftl文件相似,我只是加入了AJAX表單校驗(yàn)所用的Javascript庫(kù),以便theme為ajax的表單標(biāo)簽使用。

    <#include "/${parameters.templateDir}/xhtml/control-close.ftl" />
    <#include "/${parameters.templateDir}/simple/form-close.ftl" />
    <#include "/${parameters.templateDir}/xhtml/form-close-validate.ftl" />
    清單10 src/template/ajax_xhtml/form-close.ftl

    這個(gè)文件與xhtml theme中的form-close.ftl文件相同。

    最后發(fā)布運(yùn)行應(yīng)用程序,大家可以發(fā)現(xiàn)在Password與Age的校驗(yàn),只有在表單提交時(shí)才發(fā)生,而且是純Javascript的校驗(yàn)。不過(guò),以上代碼還不是很完善,在行為上有些BUG。

    總結(jié)

    Struts 2相比一些其它的框架,在實(shí)現(xiàn)AJAX方面的確簡(jiǎn)單很多。更激動(dòng)人心的是Struts 2的標(biāo)簽庫(kù)支持基于模板的輸出,使得開(kāi)發(fā)者可以跟據(jù)自身的需要方便地改變標(biāo)簽的行為。

    在將要發(fā)布的Struts 2.1版本中,AJAX表單校驗(yàn)將不再使用DWR,統(tǒng)一使用DOJO實(shí)現(xiàn),詳情請(qǐng)參考:http://struts.apache.org/2.0.9/docs/ajax-validation.html

    posted on 2008-09-17 15:40 綠茶_鄭州 閱讀(127) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
     
    Copyright © 綠茶_鄭州 Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 久久国产乱子伦免费精品| 中文字幕精品三区无码亚洲| 最新国产AV无码专区亚洲 | 亚洲精品无码日韩国产不卡av| 亚洲精品午夜久久久伊人| 2022年亚洲午夜一区二区福利 | 老汉色老汉首页a亚洲| 久久国产福利免费| 亚洲午夜电影一区二区三区| 亚洲成a人片77777群色| 亚洲制服丝袜一区二区三区| 亚洲AV无码一区二区三区在线| 亚洲一区二区三区乱码A| 亚洲一级片内射网站在线观看| 国产av无码专区亚洲av果冻传媒| 日韩亚洲一区二区三区| 久久久久亚洲AV无码永不| 亚洲午夜成激人情在线影院| 亚洲中文字幕无码久久2020 | 国产亚洲成AV人片在线观黄桃| 久久国产精品亚洲一区二区| 亚洲最新在线视频| 亚洲日韩看片无码电影| 黄床大片30分钟免费看| 中国在线观看免费的www| 久久久久国产精品免费看| 精品成在人线AV无码免费看| 成全高清视频免费观看| 免费乱理伦在线播放| AV大片在线无码永久免费| 夜夜嘿视频免费看| 97碰公开在线观看免费视频| 99久久免费精品国产72精品九九| 四虎永久免费地址在线观看| 久久久精品国产亚洲成人满18免费网站 | 4虎永免费最新永久免费地址| 四虎在线免费播放| 亚洲宅男天堂在线观看无病毒| 亚洲国产美女在线观看| 国产天堂亚洲国产碰碰| 久久久久久久99精品免费观看|