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

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

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

    隨筆-34  評論-1965  文章-0  trackbacks-0
    All Input Is Evil!
    -Writing secure code

    在寫前幾篇文章的時候,有些朋友建議我的寫一篇關于表單數據校驗的文章。 正如文章的開頭所引用的《Writing Secure Code》的名言:“所有的輸入都是罪惡的”,所以我們應該對所有的外部輸入進行校驗。而表單是應用程序最簡單的入口,對其傳進來的數據,我們必須進行校驗。

    轉換與校驗(Conversion & Validation)

    其實上篇文章,我本來是打算寫表單數據校驗的內容,但是經過再三思考后,還是決定先寫Struts 2.0轉換器的內容。原因是我認為轉換是校驗的基礎,只有在數據被正確地轉換成其對應的類型后,我們才可以對其取值范圍進行校驗。看個例子相信大家可以更清楚。現在我們就來改造一下《轉換器(Converter)——Struts 2.0中的魔術師》的第一個例子。

    首先,從Action開始,修改后的代碼如下:

    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中國際化的工具類,<s:text>標志就是通過調用它實現國際化的
    ?? ?? ? ? ?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中加入錯誤提示:

    <% @ 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文件,將內容改為:

    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 ;
    ? ?}

    }

    之后,修改國際化資源文件,內容為:

    HelloWorld = 你好,世界!
    invalid.fieldvalue.loc
    = Locale必須為\ " xx_XX\ " 的格式
    validation.loc
    = 區域必須為中國或美國
    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

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

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

    上述的輸出說明了Struts 2.0的數據校驗工作方式,它需要經過下面幾個步驟:

    1. 通過轉換器將請求參數轉換成相應的Bean屬性;
    2. 判斷轉換過程是否出現異常。如果有,則將其保存到ActionContext中,conversionError攔截器再封裝為fieldError;如果沒有,進行下一步;
    3. 通過反射(Reflection)來調用validateXxx()方法(其中,Xxx表示Action的方法名);
    4. 調用validate()方法;
    5. 如果經過上述步驟沒有出現fieldError,則調用Action方法;如果有,則會跳過Action方法,通過國際化將fieldError輸出到頁面。

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

    圖1 校驗順序圖
    圖1 校驗順序圖

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

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

    在運行上面的例子時,在Locale中輸入zh并提交時出現圖2所示頁面。

    圖2 錯誤格式
    圖2 錯誤格式

    在Locale中輸入de_DE時,出現如圖3所示頁面。

    圖3 取值錯誤
    圖3 取值錯誤

    使用Struts 2.0的校驗框架

    上一節的內容都是關于如何編程實現校驗,這部分工作大都是單調的重復。更多情況下,我們使用Struts 2.0的校驗框架,通過配置實現一些常見的校驗。

    我學習編程有個習慣——喜歡先看輸出結果,再看代碼實現。這樣學的好處是先看結果可以刺激學習的激情,也可以在看代碼前自已思考一下如何實現,然后帶著問題去看代碼,那就清晰多了。因此下面我們先來做演示。

    首先,在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 >

    接著,創建Input.jsp和Output.jsp,內容分別如下:

    <% @ page ?contentType = " text/html; charset=UTF-8 " %>
    <% @taglib prefix = " s " uri = " /struts-tags " %>
    < html >
    < head >
    ? ?
    < title > Hello World </ title >
    ? ?
    <!-- 此標志的作用是引入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

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

    <? 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 >

    發布運行應用程序,在地址欄中鍵入http://localhost:8080/Struts2_Validation/Input.jsp,出現如圖4所示頁面。

    圖4 Input.jsp
    圖4 Input.jsp

    直接點擊“Submit”提交表單,出現圖5所示的頁面。

    圖5 錯誤提示
    圖5 錯誤提示

    在Required String中隨便填點東西,轉到Output.jsp頁面,如圖6所示。

    圖6 Output.jsp
    圖6 Output.jsp

    通過上面的例子,大家可以看到使用該校驗框架十分簡單方便。不過,上例還有兩點不足:

    1. 還沒有國際化錯誤消息;
    2. 沒有實現客戶端的校驗。

    當然,要完善以上不足,對于Struts 2.0來說,只是小菜一碟。

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

    下面是具體的實現,首先在國際化資源文件中加入錯誤消息,然后按照上面說明實現。因為要使用Javascript在客戶端顯示出錯信息,所以在加載Input.jsp頁面時,Struts 2.0需要獲得國際化的字符串,故我們需要使用Action來訪問Input.jsp頁面,具體實現請參考《在Struts 2.0中國際化(i18n)您的應用程序》的最后部分。最后發布運行應用程序,直接在頁面中點擊“Submit”,表單沒有被提交并出現錯誤提示,如圖7所示:

    圖7 客戶端校驗
    圖7 客戶端校驗

    校驗框架是通過validation攔截器實現,該攔載被注冊到默認的攔截器鏈中。它在conversionError攔截器之后,在validateXxx()之前被調用。這里又出現了一個選擇的問題:到底是應該在action中通過validateXxx()或validate()實現校驗,還是使用validation攔截器?絕大多數情況,我建議大家使用校驗框架,只有當框架滿足不了您的要求才自已編寫代碼實現。

    配置文件查找順序

    在上面的例子中,我們通過創建ValidationAction-validation.xml來配置表單校驗。Struts 2.0的校驗框架自動會讀取該文件,但這樣就會引出一個問題——如果我的Action繼承其它的Action類,而這兩個Action類都需要對表單數據進行校驗,那我是否會在子類的配置文件(Xxx-validation.xml)中復制父類的配置嗎?

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

    1. 接口 Animal;
    2. 接口 Quadraped 擴展了 Animal;
    3. 類 AnimalImpl 實現了 Animal;
    4. 類 QuadrapedImpl 擴展了 AnimalImpl 實現了 Quadraped;
    5. 類 Dog 擴展了 QuadrapedImpl;

    如果Dog要被校驗,框架方法會查找下面的配置文件(其中別名是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

    已有的校驗器

    Struts 2.0已經為您實現很多常用的校驗了,以下在jar的default.xml中的注冊的校驗器。

    < 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 >
    關于每個校驗器的具體用法,請參考以下鏈接:
    http://wiki.javascud.org/display/ww2cndoc/Validation
    該鏈接中還有一些很有的信息,請大家仔細閱讀。

    總結

    使用校驗框架既可以方便地實現表單數據校驗,又能夠將校驗與Action分離,故我們應該盡可能使用校驗框架。在使用校驗框架時,請不要忘記通過在資源文件加入invalid.fieldvalue.xxx字符串,顯示適合的類型轉換出錯信息;或者使用conversion校驗器。

    posted on 2006-11-14 13:38 Max 閱讀(51492) 評論(118)  編輯  收藏 所屬分類: Struts 2.0系列
    評論共2頁: 上一頁 1 2 

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

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

    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]
    ----------  回復  更多評論
      
    # re: 在Struts 2.0中實現表單數據校驗(Validation) 2007-04-18 17:40 | huhuyeah
    看了這篇文章實驗了一下客戶端驗證
    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>


    校驗的xml配置就是必須要username跟password
    配置之后,服務器端的驗證已經成功了
    不過奇怪的是,看了幫助文件,在form標簽里面加入validate="true" 之后,客戶端的校驗卻不起作用
    生產的源文件沒有js也沒有onsubmit,請幫忙看看原因。謝謝   回復  更多評論
      
    # re: 在Struts 2.0中實現表單數據校驗(Validation) 2007-04-18 22:54 | Max
    @huhuyeah
    你可以忘記在<head></head>中加入<s:head />  回復  更多評論
      
    # re: 在Struts 2.0中實現表單數據校驗(Validation) 2007-04-19 09:16 | huhuyeah
    謝博主,加了這后生產的頁面源碼有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>
    但是客戶端驗證還是沒有成功
    生成的form沒有onsubmit,如果把 validate="true" 去掉。
    在form里面有onsubmit="return true"的js生成
    如何調用生成的JS?
      回復  更多評論
      
    # re: 在Struts 2.0中實現表單數據校驗(Validation)[未登錄] 2007-04-19 17:42 | test
    把validate="true"這個加上之后會出現
    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.......  回復  更多評論
      
    評論共2頁: 上一頁 1 2 
    主站蜘蛛池模板: 好看的亚洲黄色经典| 亚洲精品无码久久久| jizz在线免费观看| 亚洲人色大成年网站在线观看| 午夜成年女人毛片免费观看| 精品国产免费一区二区三区香蕉| 亚洲AV电影天堂男人的天堂| 亚洲午夜精品一区二区公牛电影院 | 亚洲国产成人久久一区久久| 中字幕视频在线永久在线观看免费| 一级特黄a免费大片| 免费看又黄又爽又猛的视频软件| 国产成人亚洲精品| 亚洲二区在线视频| 亚洲91精品麻豆国产系列在线 | 色播在线永久免费视频网站| 亚洲AV性色在线观看| 久久人午夜亚洲精品无码区| 亚洲欧好州第一的日产suv| 国产精品亚洲专区在线观看| 亚洲黄色在线电影| 亚洲中文字幕人成乱码 | 天天拍拍天天爽免费视频| 中文字幕av无码无卡免费| 亚洲中文无码永久免费| 亚洲av无码无线在线观看| 亚洲性无码一区二区三区| 精品无码专区亚洲| 香蕉国产在线观看免费| 污污网站18禁在线永久免费观看| 久9久9精品免费观看| 97国产免费全部免费观看| 性感美女视频免费网站午夜 | 国产亚洲Av综合人人澡精品| 成人久久久观看免费毛片| 国产麻豆一精品一AV一免费| 久久精品网站免费观看| 国产亚洲精品成人a v小说| 亚洲欧洲日产国码www| 色婷婷精品免费视频| 57pao国产成视频免费播放|