隨筆-34  評(píng)論-1965  文章-0  trackbacks-0
          All Input Is Evil!
          -Writing secure code

          在寫(xiě)前幾篇文章的時(shí)候,有些朋友建議我的寫(xiě)一篇關(guān)于表單數(shù)據(jù)校驗(yàn)的文章。 正如文章的開(kāi)頭所引用的《Writing Secure Code》的名言:“所有的輸入都是罪惡的”,所以我們應(yīng)該對(duì)所有的外部輸入進(jìn)行校驗(yàn)。而表單是應(yīng)用程序最簡(jiǎn)單的入口,對(duì)其傳進(jìn)來(lái)的數(shù)據(jù),我們必須進(jìn)行校驗(yàn)。

          轉(zhuǎn)換與校驗(yàn)(Conversion & Validation)

          其實(shí)上篇文章,我本來(lái)是打算寫(xiě)表單數(shù)據(jù)校驗(yàn)的內(nèi)容,但是經(jīng)過(guò)再三思考后,還是決定先寫(xiě)Struts 2.0轉(zhuǎn)換器的內(nèi)容。原因是我認(rèn)為轉(zhuǎn)換是校驗(yàn)的基礎(chǔ),只有在數(shù)據(jù)被正確地轉(zhuǎn)換成其對(duì)應(yīng)的類(lèi)型后,我們才可以對(duì)其取值范圍進(jìn)行校驗(yàn)。看個(gè)例子相信大家可以更清楚。現(xiàn)在我們就來(lái)改造一下《轉(zhuǎn)換器(Converter)——Struts 2.0中的魔術(shù)師》的第一個(gè)例子。

          首先,從Action開(kāi)始,修改后的代碼如下:

          package tutorial;

          import java.util.Locale;

          import com.opensymphony.xwork2.ActionSupport;
          import com.opensymphony.xwork2.util.LocalizedTextUtil;

          public class HelloWorld extends ActionSupport {
          ? ?
          private String msg;
          ? ?
          private Locale loc = Locale.US;
          ? ?
          ? ?
          public String getMsg() {
          ? ? ? ?
          return msg; ? ? ? ?
          ? ?}

          ? ?
          ? ?
          public Locale getLoc() {
          ? ? ? ?
          return loc;
          ? ?}

          ? ?
          ? ?
          public void setLoc(Locale loc) {
          ? ? ? ?
          this .loc = loc;
          ? ?}

          ? ?
          ? ?@Override
          ? ?
          public void validate() {
          ? ? ? ?System.out.println(
          " Calling validate() " );
          ? ? ? ?
          if ( ! (loc.equals(Locale.US) || loc.equals(Locale.CHINA))) {
          ? ? ? ? ? ? ? ? ? ?addFieldError(
          " loc " , getText( " validation.loc " ));
          ? ? ? ?}

          ? ?}

          ? ? ? ?
          ? ?
          public void validateExecute() {
          ? ? ? ?System.out.println(
          " Calling validateExecute() by reflection " );
          ? ?}

          ? ?
          ? ?@Override
          ? ?
          public String execute() {
          ? ? ? ?System.out.println(
          " Calling execute() " );
          ? ? ? ?
          // LocalizedTextUtil是Struts 2.0中國(guó)際化的工具類(lèi),<s:text>標(biāo)志就是通過(guò)調(diào)用它實(shí)現(xiàn)國(guó)際化的
          ?? ?? ? ? ?msg = LocalizedTextUtil.findDefaultText( " HelloWorld " , loc);
          ? ? ? ?
          return SUCCESS;
          ? ?}

          }

          然后,修改Struts.xml中Action的定義指明輸入地址:

          < action name ="HelloWorld" class ="tutorial.HelloWorld" >
          ? ?
          < result > /HelloWorld.jsp </ result >
          ? ?
          < result name ="input" > /HelloWorld.jsp </ result >
          </ action >

          接著,在HelloWorld.jsp中加入錯(cuò)誤提示:

          <% @ page ?contentType = " text/html; charset=UTF-8 " %>
          <% @taglib prefix = " s " uri = " /struts-tags " %>
          < html >
          < head >
          ? ?
          < title > Hello World </ title >
          </ head >
          < body >
          ? ?
          < div style ="color:red;" >
          ? ? ? ?
          < s:fielderror />
          ? ?
          </ div >
          ? ?
          < s:form action ="HelloWorld" theme ="simple" > ? ? ? ? ? ?
          ? ? ? ? Locale:
          < s:textfield name ="loc" /> &nbsp; < s:submit />
          ? ?
          </ s:form > ? ?
          ? ?
          < h2 >< s:property value ="msg" /></ h2 >
          </ body >
          </ html >

          再修改LocaleConverter.java文件,將內(nèi)容改為:

          package tutorial;

          import java.util.Locale;
          import java.util.Map;
          import java.util.regex.Pattern;

          public class LocaleConverter extends ognl.DefaultTypeConverter {
          ? ?@Override
          ? ?
          public Object convertValue(Map context, Object value, Class toType) {
          ? ? ? ?
          if (toType == Locale. class ) { ? ? ? ? ? ?
          ? ? ? ? ? ?System.out.println(
          " Converting String to Locale " );
          ? ? ? ? ? ?String locale
          = ((String[]) value)[ 0 ];
          ? ? ? ? ? ?
          return new Locale(locale.substring( 0 , 2 ), locale.substring( 3 ));
          ? ? ? ?}
          else if (toType == String. class ) {
          ? ? ? ? ? ?System.out.println(
          " Converting Locale to String " );
          ? ? ? ? ? ?Locale locale
          = (Locale) value;
          ? ? ? ? ? ?
          return locale.toString();
          ? ? ? ?}

          ? ? ? ?
          return null ;
          ? ?}

          }

          之后,修改國(guó)際化資源文件,內(nèi)容為:

          HelloWorld = 你好,世界!
          invalid.fieldvalue.loc
          = Locale必須為\ " xx_XX\ " 的格式
          validation.loc
          = 區(qū)域必須為中國(guó)或美國(guó)
          globalMessages_zh_CN.properties

          HelloWorld = Hello World!
          invalid.fieldvalue.loc
          = Locale must like \ " xx_XX\ "
          validation.loc
          = Locale must be China or USA
          globalMessages_en_US.properties

          發(fā)布運(yùn)行應(yīng)用程序,在瀏覽器中鍵入http://localhost:8080/Struts2_Validation/HelloWorld.action,在Locale中輸入zh_CN,按“Submit”提交,效果如上篇文章所示。而在服務(wù)器控制臺(tái)有如下輸出:

          Converting String to Locale...
          Calling validateExecute() by reflection...
          Calling validate()...
          Calling execute()...
          Converting Locale to String...

          上述的輸出說(shuō)明了Struts 2.0的數(shù)據(jù)校驗(yàn)工作方式,它需要經(jīng)過(guò)下面幾個(gè)步驟:

          1. 通過(guò)轉(zhuǎn)換器將請(qǐng)求參數(shù)轉(zhuǎn)換成相應(yīng)的Bean屬性;
          2. 判斷轉(zhuǎn)換過(guò)程是否出現(xiàn)異常。如果有,則將其保存到ActionContext中,conversionError攔截器再封裝為fieldError;如果沒(méi)有,進(jìn)行下一步;
          3. 通過(guò)反射(Reflection)來(lái)調(diào)用validateXxx()方法(其中,Xxx表示Action的方法名);
          4. 調(diào)用validate()方法;
          5. 如果經(jīng)過(guò)上述步驟沒(méi)有出現(xiàn)fieldError,則調(diào)用Action方法;如果有,則會(huì)跳過(guò)Action方法,通過(guò)國(guó)際化將fieldError輸出到頁(yè)面。

          不喜歡看文字的朋友,可以參考下面的圖1。

          圖1 校驗(yàn)順序圖
          圖1 校驗(yàn)順序圖

          看到這里可能大家會(huì)疑問(wèn):“這么多地方可以校驗(yàn)表單數(shù)據(jù),到底我應(yīng)該在那里做呢?”有選擇是好事,但抉擇的過(guò)程往往是痛苦的,往往讓人不知所措。如果大家參照以下幾點(diǎn)建議,相信會(huì)比較容易地做出正確的抉擇。

          1. 如果需要轉(zhuǎn)換的數(shù)據(jù),通常做法在轉(zhuǎn)換的時(shí)候做格式的校驗(yàn),在Action中的校驗(yàn)方法中校驗(yàn)取值。假如用戶填錯(cuò)了格式,我們可以通過(guò)在資源文件配置invalid.fieldvalue.xxx(xxx為屬性名)來(lái)提示用戶正確的格式,不同的階段出錯(cuò)顯示不同的信息。具體做法請(qǐng)參考上面的例子;
          2. 至于用validate()還是validateXxx(),我推薦使用validate()。原因是validateXxx()使用了反射,相對(duì)來(lái)說(shuō)性能稍差,而validate()則是通過(guò)接口com.opensymphony.xwork2.Validateable調(diào)用。當(dāng)然如果你的表單數(shù)據(jù)取值是取決于特定Action方法,則應(yīng)該使用validateXxx()。

          在運(yùn)行上面的例子時(shí),在Locale中輸入zh并提交時(shí)出現(xiàn)圖2所示頁(yè)面。

          圖2 錯(cuò)誤格式
          圖2 錯(cuò)誤格式

          在Locale中輸入de_DE時(shí),出現(xiàn)如圖3所示頁(yè)面。

          圖3 取值錯(cuò)誤
          圖3 取值錯(cuò)誤

          使用Struts 2.0的校驗(yàn)框架

          上一節(jié)的內(nèi)容都是關(guān)于如何編程實(shí)現(xiàn)校驗(yàn),這部分工作大都是單調(diào)的重復(fù)。更多情況下,我們使用Struts 2.0的校驗(yàn)框架,通過(guò)配置實(shí)現(xiàn)一些常見(jiàn)的校驗(yàn)。

          我學(xué)習(xí)編程有個(gè)習(xí)慣——喜歡先看輸出結(jié)果,再看代碼實(shí)現(xiàn)。這樣學(xué)的好處是先看結(jié)果可以刺激學(xué)習(xí)的激情,也可以在看代碼前自已思考一下如何實(shí)現(xiàn),然后帶著問(wèn)題去看代碼,那就清晰多了。因此下面我們先來(lái)做演示。

          首先,在tutorial包下新建ValidationAction.java,代碼如下:

          package tutorial;

          import com.opensymphony.xwork2.ActionSupport;

          public class ValidationAction extends ActionSupport {
          ? ?
          private String reqiuredString;

          ? ?
          public String getReqiuredString() {
          ? ? ? ?
          return reqiuredString;
          ? ?}


          ? ?
          public void setReqiuredString(String reqiuredString) {
          ? ? ? ?
          this .reqiuredString = reqiuredString;
          ? ?}

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

          然后,配置上述所建的Ation,代碼片段如下:

          < action name ="ValidationAction" class ="tutorial.ValidationAction" >
          ? ?
          < result > /Output.jsp </ result >
          ? ?
          < result name ="input" > /Input.jsp </ result >
          </ action >

          接著,創(chuàng)建Input.jsp和Output.jsp,內(nèi)容分別如下:

          <% @ page ?contentType = " text/html; charset=UTF-8 " %>
          <% @taglib prefix = " s " uri = " /struts-tags " %>
          < html >
          < head >
          ? ?
          < title > Hello World </ title >
          ? ?
          <!-- 此標(biāo)志的作用是引入Struts 2.0的常用的Javascript和CSS -->
          ? ?
          < s:head />
          </ head >
          < body >
          ? ?
          < s:form action ="ValidationAction" > ? ? ? ? ? ?
          ? ? ? ?
          < s:textfield name ="reqiuredString" label ="Required String" />
          ? ? ? ?
          < s:submit />
          ? ?
          </ s:form > ? ?
          </ body >
          </ html >
          Input.jsp

          <% @ page ?contentType = " text/html; charset=UTF-8 " %>
          <% @taglib prefix = " s " uri = " /struts-tags " %>
          < html >
          < head >
          ? ?
          < title > Hello World </ title >
          </ head >
          < body >
          ? ? Required String:
          < s:property value ="reqiuredString" /> ? ?
          </ body >
          </ html >
          Output.jsp

          再接下來(lái),在tutorial包下創(chuàng)建ValidationAction的校驗(yàn)配置文件Xxx-validation.xml(Xxx為Action的類(lèi)名),在本例中該文件名ValidationAction-validation.xml,內(nèi)容如下:

          <? xml version="1.0" encoding="UTF-8" ?>
          <! DOCTYPE validators PUBLIC?
          ? ? ? ? ? "-//OpenSymphony Group//XWork Validator 1.0//EN"?
          ? ? ? ? ? "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"
          > ? ? ? ? ?
          < validators >
          ? ?
          < field name ="reqiuredString" >
          ? ? ? ?
          < field-validator type ="requiredstring" >
          ? ? ? ? ? ?
          < message > This string is required </ message >
          ? ? ? ?
          </ field-validator >
          ? ?
          </ field >
          </ validators >

          發(fā)布運(yùn)行應(yīng)用程序,在地址欄中鍵入http://localhost:8080/Struts2_Validation/Input.jsp,出現(xiàn)如圖4所示頁(yè)面。

          圖4 Input.jsp
          圖4 Input.jsp

          直接點(diǎn)擊“Submit”提交表單,出現(xiàn)圖5所示的頁(yè)面。

          圖5 錯(cuò)誤提示
          圖5 錯(cuò)誤提示

          在Required String中隨便填點(diǎn)東西,轉(zhuǎn)到Output.jsp頁(yè)面,如圖6所示。

          圖6 Output.jsp
          圖6 Output.jsp

          通過(guò)上面的例子,大家可以看到使用該校驗(yàn)框架十分簡(jiǎn)單方便。不過(guò),上例還有兩點(diǎn)不足:

          1. 還沒(méi)有國(guó)際化錯(cuò)誤消息;
          2. 沒(méi)有實(shí)現(xiàn)客戶端的校驗(yàn)。

          當(dāng)然,要完善以上不足,對(duì)于Struts 2.0來(lái)說(shuō),只是小菜一碟。

          1. 在Xxx-validation.xml文件中的<message>元素中加入key屬性;
          2. 在Input.jsp中的<s:form>標(biāo)志中加入validate="true"屬性,就可以在用Javascript在客戶端校驗(yàn)數(shù)據(jù)。

          下面是具體的實(shí)現(xiàn),首先在國(guó)際化資源文件中加入錯(cuò)誤消息,然后按照上面說(shuō)明實(shí)現(xiàn)。因?yàn)橐褂肑avascript在客戶端顯示出錯(cuò)信息,所以在加載Input.jsp頁(yè)面時(shí),Struts 2.0需要獲得國(guó)際化的字符串,故我們需要使用Action來(lái)訪問(wèn)Input.jsp頁(yè)面,具體實(shí)現(xiàn)請(qǐng)參考《在Struts 2.0中國(guó)際化(i18n)您的應(yīng)用程序》的最后部分。最后發(fā)布運(yùn)行應(yīng)用程序,直接在頁(yè)面中點(diǎn)擊“Submit”,表單沒(méi)有被提交并出現(xiàn)錯(cuò)誤提示,如圖7所示:

          圖7 客戶端校驗(yàn)
          圖7 客戶端校驗(yàn)

          校驗(yàn)框架是通過(guò)validation攔截器實(shí)現(xiàn),該攔載被注冊(cè)到默認(rèn)的攔截器鏈中。它在conversionError攔截器之后,在validateXxx()之前被調(diào)用。這里又出現(xiàn)了一個(gè)選擇的問(wèn)題:到底是應(yīng)該在action中通過(guò)validateXxx()或validate()實(shí)現(xiàn)校驗(yàn),還是使用validation攔截器?絕大多數(shù)情況,我建議大家使用校驗(yàn)框架,只有當(dāng)框架滿足不了您的要求才自已編寫(xiě)代碼實(shí)現(xiàn)。

          配置文件查找順序

          在上面的例子中,我們通過(guò)創(chuàng)建ValidationAction-validation.xml來(lái)配置表單校驗(yàn)。Struts 2.0的校驗(yàn)框架自動(dòng)會(huì)讀取該文件,但這樣就會(huì)引出一個(gè)問(wèn)題——如果我的Action繼承其它的Action類(lèi),而這兩個(gè)Action類(lèi)都需要對(duì)表單數(shù)據(jù)進(jìn)行校驗(yàn),那我是否會(huì)在子類(lèi)的配置文件(Xxx-validation.xml)中復(fù)制父類(lèi)的配置嗎?

          答案是不,因?yàn)镾truts 2.0的校驗(yàn)框架跟《在Struts 2.0中國(guó)際化(i18n)您的應(yīng)用程序》提到的“資源文件查找順序”相似,有特定的配置文件查找順序。不同的是校驗(yàn)框架按照自上而下的順序在類(lèi)層次查找配置文件。假設(shè)以下條件成立:

          1. 接口 Animal;
          2. 接口 Quadraped 擴(kuò)展了 Animal;
          3. 類(lèi) AnimalImpl 實(shí)現(xiàn)了 Animal;
          4. 類(lèi) QuadrapedImpl 擴(kuò)展了 AnimalImpl 實(shí)現(xiàn)了 Quadraped;
          5. 類(lèi) Dog 擴(kuò)展了 QuadrapedImpl;

          如果Dog要被校驗(yàn),框架方法會(huì)查找下面的配置文件(其中別名是Action在struts.xml中定義的別名):

          1. Animal-validation.xml
          2. Animal-別名-validation.xml
          3. AnimalImpl-validation.xml
          4. AnimalImpl-別名-validation.xml
          5. Quadraped-validation.xml
          6. Quadraped-別名-validation.xml
          7. QuadrapedImpl-validation.xml
          8. QuadrapedImpl-別名-validation.xml
          9. Dog-validation.xml
          10. Dog-別名-validation.xml

          已有的校驗(yàn)器

          Struts 2.0已經(jīng)為您實(shí)現(xiàn)很多常用的校驗(yàn)了,以下在jar的default.xml中的注冊(cè)的校驗(yàn)器。

          < validators >
          ? ?
          < validator name ="required" class ="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator" />
          ? ?
          < validator name ="requiredstring" class ="com.opensymphony.xwork2.validator.validators.RequiredStringValidator" />
          ? ?
          < validator name ="int" class ="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator" />
          ? ?
          < validator name ="double" class ="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator" />
          ? ?
          < validator name ="date" class ="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator" />
          ? ?
          < validator name ="expression" class ="com.opensymphony.xwork2.validator.validators.ExpressionValidator" />
          ? ?
          < validator name ="fieldexpression" class ="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator" />
          ? ?
          < validator name ="email" class ="com.opensymphony.xwork2.validator.validators.EmailValidator" />
          ? ?
          < validator name ="url" class ="com.opensymphony.xwork2.validator.validators.URLValidator" />
          ? ?
          < validator name ="visitor" class ="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator" />
          ? ?
          < validator name ="conversion" class ="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator" />
          ? ?
          < validator name ="stringlength" class ="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator" />
          ? ?
          < validator name ="regex" class ="com.opensymphony.xwork2.validator.validators.RegexFieldValidator" />
          </ validators >
          關(guān)于每個(gè)校驗(yàn)器的具體用法,請(qǐng)參考以下鏈接:
          http://wiki.javascud.org/display/ww2cndoc/Validation
          該鏈接中還有一些很有的信息,請(qǐng)大家仔細(xì)閱讀。

          總結(jié)

          使用校驗(yàn)框架既可以方便地實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn),又能夠?qū)⑿r?yàn)與Action分離,故我們應(yīng)該盡可能使用校驗(yàn)框架。在使用校驗(yàn)框架時(shí),請(qǐng)不要忘記通過(guò)在資源文件加入invalid.fieldvalue.xxx字符串,顯示適合的類(lèi)型轉(zhuǎn)換出錯(cuò)信息;或者使用conversion校驗(yàn)器。

          posted on 2006-11-14 13:38 Max 閱讀(51499) 評(píng)論(118)  編輯  收藏 所屬分類(lèi): Struts 2.0系列
          評(píng)論共2頁(yè): 上一頁(yè) 1 2 

          評(píng)論:
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-11-15 15:51 | ronghai
          你好怎么樣才能聯(lián)系到你,好好了解一些struts2。發(fā)現(xiàn)1.X和2有太大的差別了,剛把1.x弄得差不多,看2覺(jué)得很不是理解。  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-11-16 09:01 | Max
          你可以通過(guò)email聯(lián)系我, max.m.yuan@gmail.com  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-11-22 13:53 | 太行山人
          正在學(xué)2.0,您寫(xiě)的太好了,收藏下來(lái)仔細(xì)研讀  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-11-27 11:43 | breezedancer
          寫(xiě)的很好,轉(zhuǎn)到我的論壇www.51forum.uni.cc,如果有什么不當(dāng),請(qǐng)聯(lián)系管理員,謝謝~~~  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-12-04 22:28 | zjlovezj
          謝謝樓主,hello world是通往實(shí)際應(yīng)用的必由之路~

          冒昧提多個(gè)要求:
          請(qǐng)寫(xiě)寫(xiě)spring2 和 struts2結(jié)合起來(lái)使用的HELLO WORLD,最好加上個(gè)hibernate3.2  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-12-06 01:30 | lhj
          嗯,,同樓上,希望老大弄個(gè)spring2和struts2甚至hibernate結(jié)合的例子,重點(diǎn)講下配置要點(diǎn)和原理,呵呵,不情之請(qǐng),見(jiàn)諒!  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-12-06 09:35 | Max
          謝謝大家的建議,我計(jì)劃在以后文章中介紹Struts 2與一些流行的框架的搭配。  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2006-12-06 10:32 | sxf
          寫(xiě)的好,加油!  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-02-01 15:59 | Sophia
          Max,最近在嘗試Struts2的Validation Annotation。發(fā)現(xiàn)@Annotation是需要引用一個(gè)com.opensymphony.xwork2.validator.annotations包下的@interface Validation。這個(gè)package被打到了xwork-2.0-beta-1.jar里面,但是struts官網(wǎng)上提供的jar里面卻并未含有這個(gè)包。
          我在網(wǎng)上找了一下,在http://ivyrep.opensymphony.com/opensymphony/xwork/ 下面找了個(gè)最新的xwork-2.0.0.jar 來(lái)用。但是tomcat啟動(dòng)的時(shí)候,報(bào)錯(cuò)struts - cleanup之類(lèi)的。換回原來(lái)的xwork-2.0-beta-1.jar就沒(méi)問(wèn)題。
          想請(qǐng)教一下,用Annotation方法如何實(shí)現(xiàn)Validation?
          謝謝。  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-02-02 12:51 | Sophia
          補(bǔ)充一下,所謂的struts - cleanup報(bào)錯(cuò)是因?yàn)樵趙eb.xml中配置了這個(gè)filter。
          同樣web.xml中配置的struts2的filter也會(huì)出錯(cuò)。
          <code>
          <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>
          </code>
          那個(gè)xwork-2.0.0.jar是webwork提供的。
          我將需要用到的幾個(gè)包單獨(dú)拉出來(lái)打包就可以了。
          com.opensymphony.xwork2.validator
          com.opensymphony.xwork2.validator.annotations
          com.opensymphony.xwork2.validator.metadata
          com.opensymphony.xwork2.validator.validators
          看來(lái)是beta版的原因啊!  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-02-02 12:52 | Sophia
          sorry, 不會(huì)貼代碼,嗬嗬,那個(gè)<code></code>請(qǐng)省略不看  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-02-13 01:21 | mos
          如何在struts2中使用js呢?  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-03-02 16:13 | z
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-03-06 16:02 | mz
          請(qǐng)問(wèn)報(bào)這個(gè)錯(cuò)是哪沒(méi)有配好?

          Method public java.lang.String com.opensymphony.xwork2.validator.validators.ValidatorSupport.getMessage(java.lang.Object) threw an exception when invoked on com.opensymphony.xwork2.validator.validators.RequiredStringValidator@156f920
          The problematic instruction:
          ----------
          ==> ${validator.getMessage(action)?js_string} [on line 28, column 26 in template/xhtml/form-close-validate.ftl]
          in include "/${parameters.templateDir}/xhtml/form-close-validate.ftl" [on line 3, column 1 in template/xhtml/form-close.ftl]
          ----------  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-04-18 17:40 | huhuyeah
          看了這篇文章實(shí)驗(yàn)了一下客戶端驗(yàn)證
          login.jsp:
          <s:fielderror></s:fielderror>
          <p>&nbsp;</p>
          <s:form action="login" validate="true">
          用戶名:<s:textfield name="username"/>
          密 碼:<s:password name="password" />
          <s:submit/>
          </s:form>

          struts.xml:
          <package name="loginout" extends="hello-default" namespace="/">
          <action name="login" class="com.jetch.action.LoginAction">
          <result name="success">/WEB-INF/jsp/main.jsp</result>
          <result name="input">/WEB-INF/jsp/login.jsp</result>
          <interceptor-ref name="defaultStack"></interceptor-ref>
          </action>
          </package>


          校驗(yàn)的xml配置就是必須要username跟password
          配置之后,服務(wù)器端的驗(yàn)證已經(jīng)成功了
          不過(guò)奇怪的是,看了幫助文件,在form標(biāo)簽里面加入validate="true" 之后,客戶端的校驗(yàn)卻不起作用
          生產(chǎn)的源文件沒(méi)有js也沒(méi)有onsubmit,請(qǐng)幫忙看看原因。謝謝   回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-04-18 22:54 | Max
          @huhuyeah
          你可以忘記在<head></head>中加入<s:head />  回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation) 2007-04-19 09:16 | huhuyeah
          謝博主,加了這后生產(chǎn)的頁(yè)面源碼有JS了,如下
          <script language="JavaScript" type="text/javascript">
          // Dojo configuration
          djConfig = {
          baseRelativePath: "/hello/struts/dojo",
          isDebug: false,
          bindEncoding: "UTF-8",
          debugAtAllCosts: true // not needed, but allows the Venkman debugger to work with the includes
          };
          </script>
          <script language="JavaScript" type="text/javascript"
          src="/hello/struts/dojo/dojo.js"></script>
          <script language="JavaScript" type="text/javascript"
          src="/hello/struts/simple/dojoRequire.js"></script>
          但是客戶端驗(yàn)證還是沒(méi)有成功
          生成的form沒(méi)有onsubmit,如果把 validate="true" 去掉。
          在form里面有onsubmit="return true"的js生成
          如何調(diào)用生成的JS?
            回復(fù)  更多評(píng)論
            
          # re: 在Struts 2.0中實(shí)現(xiàn)表單數(shù)據(jù)校驗(yàn)(Validation)[未登錄](méi) 2007-04-19 17:42 | test
          把validate="true"這個(gè)加上之后會(huì)出現(xiàn)
          FreeMarker template error!

          Method public java.lang.String com.opensymphony.xwork2.validator.validators.ValidatorSupport.getMessage(java.lang.Object) threw an exception when invoked on com.opensymphony.xwork2.validator.validators.RequiredStringValidator@10699ea
          The problematic instruction:
          ----------
          ==> ${validator.getMessage(action)?js_string} [on line 28, column 26 in template/xhtml/form-close-validate.ftl]
          in include "/${parameters.templateDir}/xhtml/form-close-validate.ftl" [on line 3, column 1 in template/xhtml/form-close.ftl]
          ----------

          Java backtrace for programmers:
          ----------
          freemarker.template.TemplateModelException: Method public java.lang.String com.opensymphony.xwork2.validator.validators.ValidatorSupport.getMessage(java.lang.Object) threw an exception when invoked on com.opensymphony.xwork2.validator.validators.RequiredStringValidator@10699ea.......  回復(fù)  更多評(píng)論
            
          評(píng)論共2頁(yè): 上一頁(yè) 1 2 
          主站蜘蛛池模板: 郯城县| 县级市| 鄂尔多斯市| 邛崃市| 丽江市| 夹江县| 伊宁市| 古蔺县| 疏附县| 安泽县| 泰来县| 无为县| 南部县| 垫江县| 镇远县| 都兰县| 城市| 舟曲县| 会泽县| 平乐县| 南岸区| 准格尔旗| 外汇| 綦江县| 合作市| 永泰县| 沐川县| 抚顺市| 松潘县| 山阴县| 罗田县| 启东市| 黄冈市| 峨山| 来安县| 枣阳市| 陆丰市| 普格县| 康定县| 江永县| 保山市|