2015年7月6日 星期一

Struts的 validate framework(Struts三)

尤於validate()好用,上次的dynaActionForm,如果不驗證,確實是不用寫form,但大部分都要驗證啊!這時就有白寫的感覺,所以有這個框架,讓validate可驗證,且ActionForm不用寫

1.刪除ActionForm
2.struts-config.xml加入plug-in,從blank copy,注意看value有兩個xml:validator-rules.xml(通常不需修改,包在jar檔內)和validation.xml struts-core-1.3.10.jar下的org.apache.struts.validator有validator-rules.xml
3.copy validateion.xml,還是從blank copy,copy到1的value的地方
4.struts-config.xml修改如下:
<form-beans>
    <!--type改成框架路徑-->
    <form-bean name="ooo" type="org.apache.struts.validator.DynaValidatorForm">
        <form-property name="username" type="java.lang.String" />
        <form-property name="password" type="java.lang.String" />
    </form-bean>
</form-beans>

Action修改如下
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {
    DynaValidatorForm dvf = (DynaValidatorForm) form;
    String username = (String) dvf.get("username");
    String password = (String) dvf.get("password");

    // action想存錯誤訊息可用這兩行
    ActionErrors errors = new ActionErrors();
    request.setAttribute(Globals.ERROR_KEY, errors);

    if (username.trim().equals("aaa") && password.trim().equals("111")) {
        return mapping.findForward("success");
    } else {
        errors.add("user", new ActionMessage("actionUP"));
        return mapping.findForward("fail");
    }
}

vadation.xml設定如下:
官方文件:struts-1.3.10/docs/faqs/validator.html
.depends可以打很多,用逗號隔開,要參考validator-rules.xml
.validator-rules.xml的required有msg="errors.required",用搜尋可得key=value,
把它整段復製到自己的properties
.name為depends裡的其中一項,key是properties的key,給{0}用的
.msg是自訂訊息; arg是用validator-rules.xml的訊息
<form name="ooo">
    <field property="username" depends="required">
    <!-- <arg key="vusername" name="required" position="0" /> -->
        <msg name="required" key="username"/>
    </field>
    <field property="password" depends="required">
        <arg key="vpassword" name="required" position="0" />
    </field>
</form>

properties
username=username can't empty
password=password can't empty 
actionUP=please Enter legal username and password!
errors.required={0} is required.
vusername=\u5E33\u865F
vpassword=\u5BC6\u78BC

index.jsp的property要改成和validation.xml的property一樣
<html:errors/>
<form action="<c:url value="/xxx.do"/>">
    帳:<input type="text" name="username" /><html:errors property="username" /><br />
    密:<input type="password" name="password" /><html:errors property="password" /><br />
    <input type="submit" value="送出" />
    <input type="reset" value="重置" />
</form>

其他檔案都和Struts(一)裡的一樣

※多個驗證可修改如下,如密碼是必填也必須是數字:

<form name="ooo">
    <field property="username" depends="required">
    <!-- <arg key="vusername" name="required" position="0" /> -->
        <msg name="required" key="username"/>
    </field>
    <field property="password" depends="required, integer">
        <arg key="vpassword" name="required" position="0" />
        <arg key="vpassword" name="integer" position="0" />
    </field>
</form>
properties也要多增加一行,從validator-rules.xml copy
username=username can't empty
password=password can't empty 
actionUP=please Enter legal username and password!
errors.required={0} is required.
vusername=\u5E33\u865F
vpassword=\u5BC6\u78BC
errors.integer={0} must be an integer.

depends加多個用逗點隔開即可,但arg的name加多個也是可以run,但key就會變成null

※date型態和範圍稍為難一點,我新增兩個欄位如下:

index.jsp
<form action="<c:url value="/xxx.do"/>">
    帳:<input type="text" name="username" />
      <html:errors property="username" /><br />
    密:<input type="password" name="password" />
      <html:errors property="password" /><br />
    範圍:<input type="text" name="intRangeTest" />
      <html:errors property="intRangeTest" /><br />
    日期:<input type="text" name="dateTest" />
      <html:errors property="dateTest" /><br />
    <input type="submit" value="送出" />
    <input type="reset" value="重置" />
</form>

struts-config.xml也要增加,注意日期的type是String,我用java.util.Date會報錯
<form-bean name="ooo" type="org.apache.struts.validator.DynaValidatorForm">
    <form-property name="username" type="java.lang.String" />
    <form-property name="password" type="java.lang.String" />
    <form-property name="intRangeTest" type="java.lang.String" />
    <form-property name="dateTest" type="java.lang.String" />
</form-bean>

validation.xml範圍我設定100~2000,日期驗證官方說是用SimpleDateFormat:
<form name="ooo">
    <field property="username" depends="required">
    <!-- <arg key="vusername" name="required" position="0" /> -->
        <msg name="required" key="username"/>
    </field>
    <field property="password" depends="required, integer">
        <arg key="vpassword" name="required" position="0" />
        <arg key="vpassword" name="integer" position="0" />
    </field>
    <field property="intRangeTest" depends="intRange">
        <arg position="0" key="vintRangeTest"/>
        <arg position="1" name="intRange" key="${var:min}" resource="false"/>
        <arg position="2" name="intRange" key="${var:max}" resource="false"/>
        <var>
            <var-name>min</var-name>
            <var-value>100</var-value>
        </var>
        <var>
            <var-name>max</var-name>
            <var-value>2000</var-value>
        </var>
    </field>
    <field property="dateTest" depends="date, required">
        <arg position="0" key="vdate" name="date"/>
        <var>
            <var-name>datePattern</var-name>
            <var-value>yyyyMMdd</var-value>
        </var>
        <arg key="vdate" name="required" position="0" />
    </field>
</form>

properties:
username=username can't empty
password=password can't empty 
actionUP=please Enter legal username and password!
errors.required={0} is required.
vusername=\u5E33\u865F
vpassword=\u5BC6\u78BC
errors.integer={0} must be an integer.
vintRangeTest=\u7BC4\u570D
errors.range={0} is not in the range {1} through {2}.
errors.date={0} is not a date.
vdate=\u65E5\u671F

※validwhen

當所有的驗證都不合乎需求時,那只好自己寫了
將jsp,struts-config都恢復成帳號和密碼兩個欄位
properties,validwhen需要用errors.required,但訊息不是我們要的,先改一下
username=username can't empty
password=password can't empty 
actionUP=please Enter legal username and password!
errors.required={0} \u9A57\u8B49\u5931\u6557
vusername=\u5E33\u865F
vpassword=\u5BC6\u78BC
errors.integer={0} must be an integer.

validation.xml,<var-value>裡面的語言自成一格,
*this*:為自己的欄位; 要抓其他欄位只要寫property裡的名字即可
寫完一定要用()包起來,否則會出「SYSTEM ERROR: Check logs for details.」的錯
<field property="username" depends="required">
    <msg name="required" key="username"/>
</field>
<field property="password" depends="integer, validwhen">
    <arg key="vpassword" name="integer" position="0" />
    <arg key="vpassword" name="validwhen" position="0" />
    <var>
        <var-name>test</var-name>
        <var-value>((*this* == '111') and (username == "aaa"))</var-value>
    </var>
</field>

※客戶端驗證

之前的全都是伺服器端的驗證,Struts也支緩客戶端驗證。 其實就是把剛剛的錯誤訊息變成alert出來
1.<html>裡加屬性 formName
2.<form>增加name和onsubmit屬性
3.我試的結果只有required (必填)有效

<html:javascript formName="ooo" /><%-- 改這行--%>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=BIG5">
    <title>Insert title here</title>
    </head>
    <body>
        <form action="<c:url value="/xxx.do"/>" name="ooo" onsubmit="validateOoo(this)"><%-- 改這行--%>
            帳:<input type="text" name="username" />
              <html:errors property="username" /><br />
            密:<input type="password" name="password" />
              <html:errors property="password" /><br />
            <input type="submit" value="送出" />
            <input type="reset" value="重置" />
        </form>
    </body>
</html>

沒有留言:

張貼留言