论坛首页 Java版 Webwork

webwork的客户端javascript校验器和普通校验器

浏览 15353 次
该帖已经被评为精华帖
作者 正文
最后更新时间:2004-12-01
已有但不采用的JavaScript验证:
邮件:规则不好
url :规则不好
int范围:没有实现检测是否int类型

date范围 (没实现)


已有的符合要求的JavaScript验证:
*必填字段
*必填字符串 (可设置是否去掉空格) ---需要实现JS的trim



要实现的JavaScript验证: (对应:表示是否有普通的检测器)
1.integer (包含plusint,short,byte)
  检测:字符串格式,范围,类型
  属性:最大,最小,类型(int,plusint,short,byte)
 
  对应:有,实现检测最大最小,是否满足类型要求
 

2.float
  检测:字符串格式,范围
  属性:最大,最小
 
  对应:有
 

3.字符串长度
  检测:范围
  属性:最大,最小,类型(多字节语言/普通) 
  对应:有
 
  注:类型多字节语言适用于多字节的字符保存到单字节设置的数据库里,否则用普通
 

4.select
  检测:多少
  属性:最少,最多
 
  对应:有?

5.checkbox,radio
    检测:多少
属性:最小 最少 

对应:有?

6.datamask数据格式(其他浏览器是否支持?)
检测:格式
属性:DataMask格式

对应: ??

7.邮件
检测:格式

对应:有

8.网址
检测:格式

对应:有

9.26个字母
检测:格式

对应:有

10.基础ascii字符
检测:格式

对应:有

11.日期
检测:格式,范围
属性:最大,最小

对应:有


12.日期时间
检测:格式,范围
属性:最大,最小

    对应:有
   
最后更新时间:2004-11-29
1.integer检测器的实现

[code:1]
package com.jscud.www.validator;

import com.opensymphony.xwork.validator.ValidationException;
import com.opensymphony.xwork.validator.validators.FieldValidatorSupport;

/**
* Integer的范围检测.
*
* @author scud
*
*/
public class IntegerValidator extends FieldValidatorSupport
{

    //最大值
    Integer maxnum = null;
    //最小值
    Integer minnum = null;
    //数据类型:int,plusint,short,byte,考虑支持long
    String datatype = "int";

    public void validate(Object object) throws ValidationException
    {
        String fieldName = getFieldName();
       
        Integer val = (Integer) getFieldValue(fieldName, object);

        //如果要检测必填,使用required检测器
        if (val == null)
        {
            return;
        }
        else
        {
            //此检测器肯定会有最小值和最大值,所以用else if
            if (( null!=getMinnum() ) && (val.intValue() < getMinnum().intValue()))
            {
                addFieldError(fieldName, object);
            }
            else if (( null!=getMaxnum() ) && (val.intValue() > getMaxnum().intValue())) 
            {
                addFieldError(fieldName, object);
            }
        }
    }

    /**
     * @return Returns the datatype.
     */
    public String getDatatype()
    {
        if (null == datatype)
        {
            datatype = getDefaultDataType();
        }
        return datatype;
    }

    /**
     * @param datatype The datatype to set.
     */
    public void setDatatype(String datatype)
    {
        this.datatype = datatype;
    }

    /**
     * @return Returns the maxnum.
     */
    public Integer getMaxnum()
    {
        if(null==maxnum)
        {
            maxnum = new Integer(getDataTypeMaxNum(getDatatype()));
        }

        return maxnum;
    }

    /**
     * @param maxnum The maxnum to set.
     */
    public void setMaxnum(Integer maxnum)
    {
        this.maxnum = maxnum;
    }

    /**
     * @return Returns the minnum.
     */
    public Integer getMinnum()
    {
        if(null==minnum)
        {
            minnum = new Integer(getDataTypeMinNum(getDatatype()));
        }
        return minnum;
    }

    /**
     * @param minnum The minnum to set.
     */
    public void setMinnum(Integer minnum)
    {
        this.minnum = minnum;
    }

    /**
     * 缺省数据类型
     * @return
     */
    protected String getDefaultDataType()
    {
        return "int";
    }

    /**
     * 得到某种类型的最大值
     * @param sDatatype
     * @return
     */
    protected int getDataTypeMaxNum(String sDatatype)
    {
        if (null == sDatatype)
        {
            sDatatype = getDefaultDataType();
        }

        if (sDatatype.equalsIgnoreCase("byte"))
        {
            return 127;
        }
        else if (sDatatype.equalsIgnoreCase("short"))
        {
            return 32767;
        }
        else
        {
            return 2147483647;
        }

    }

    /**
     * 得到某种类型的最小值
     * @param sDatatype
     * @return
     */
    protected int getDataTypeMinNum(String sDatatype)
    {
        if (null == sDatatype)
        {
            sDatatype = getDefaultDataType();
        }

        if (sDatatype.equalsIgnoreCase("byte"))
        {
            return -128;
        }
        else if (sDatatype.equalsIgnoreCase("short"))
        {
            return -32768;
        }
        else if (sDatatype.equalsIgnoreCase("plusint"))
        {
            return 0;
        }
        else
        {
            return -2147483648;
        }

    }

}
[/code:1]


Javascript检测的: (为了简单,自己要包含checkform.js在文件里,否则代码太多)

[code:1]

package com.jscud.www.validator;

import java.util.Map;

import com.opensymphony.webwork.validators.ScriptValidationAware;


/**
* 检测是否integer.必须自己包含checkform.js
*
* @author scud
*
*/
public class JSIntegerValidator extends IntegerValidator implements
        ScriptValidationAware
{

    /* javascript
     */
    public String validationScript(Map parameters)
    {
        String field = (String) parameters.get("name");
        StringBuffer js = new StringBuffer();

        js.append("value = form.elements['" + field + "'].value; \n");
       
        js.append("if ( !validateInteger(value) ");
       
        if(null!=getMaxnum())
        {
            js.append(" && !validateIntMax(value,");
            js.append(getMaxnum());
            js.append(") ");
        }
        if(null!=getMinnum())
        {
            js.append(" && !validateIntMin(value,");
            js.append(getMinnum());
            js.append(") ");
        }

        js.append( " ) { \n");
        js.append("\t alert('" + getMessage(null) + "'); \n");
        js.append("\t return '" + field + "'; \n");
        js.append("} \n");
        js.append("\n");
       

        return js.toString();

    }
   
}

[/code:1]
   
0 请登录后投票
最后更新时间:2004-11-26
第一个检测器用到的checkform.js的内容

[code:1]


//是否为合法数字:不支持-0x
function isAllDigits(argvalue)
{
    argvalue = argvalue.toString();
    var validChars = "0123456789";
    var startFrom = 0;
    if (argvalue.substring(0, 2) == "0x")
    {
        validChars = "0123456789abcdefABCDEF";
        startFrom = 2;
    }
    else if (argvalue.charAt(0) == "0")
    {
        validChars = "01234567";
        startFrom = 1;
    }
    else if (argvalue.charAt(0) == "-")
    {
        startFrom = 1;
    }

    for (var n = startFrom; n < argvalue.length; n++)
    {
        if (validChars.indexOf(argvalue.substring(n, n + 1)) ==  - 1)
            return false;
    }
    return true;
}



//检测integer,plusint,byte,short
function validateInteger(aInt)
{
if(aInt.length==0) return true;

    if (!isAllDigits(aInt))
    {
        return false;
    }
    else
    {
        var iValue = parseInt(aInt);
        if (isNaN(iValue) )
        { return false; }
    }
    return true;
}

function validateIntMax(aInt,aMax)
{   
    var fValue = parseInt(aInt);
    if (fValue > aMax)
    {
    return false;
    }
    return true;
}

//检查一个Int的范围
function validateIntMin(aInt,aMin)
{
    var fValue = parseInt(aInt);
    if (fValue < aMin )
    {
    return false;
    }
    return true;
}
[/code:1]
   
0 请登录后投票
最后更新时间:2004-11-26
这么麻烦干什么? 扩展一个正则表达式的校验不就搞定所有的了么?
   
0 请登录后投票
最后更新时间:2004-11-26
既然如此,那我不发了 嘿嘿

但是对你的想法我持保留意见,而且我想我应该不会用一个校验器来对付所有的检测,正则表达式不是人人都熟悉的,尽管我很熟悉perl的正则表达式.
   
0 请登录后投票
最后更新时间:2004-11-26
偶的意思是先写一个正则表达式的校验器, 你熟悉它, 那么当然直接用表达式来校验, 比如email:

<field name="email">
    <field-validator type="regexp">
        <param name="expression">(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})</param>
        <message>Not a valid email address</message>
    </field-validator>
</field>

你也可以扩展这个校验器, 把这个一堆符号放在代码里, 不懂regexp的人, 就可以这样直接调用:

<field name="email">
    <field-validator type="emailregexp">
        <message>Not a valid email address</message>
    </field-validator>
</field>

而不是像现在这样做一堆重复代码......
   
0 请登录后投票
最后更新时间:2004-11-26
我没仔细研究过javascript里面的正则表达式

但是我觉得他们可能有些不一样

所以如果一个校验器既用来在服务器端校验又用来在客户端校验,用到的表达式可能有些不一样. (写2个? 也许可以 )

同时考虑的问题还有一些客户端的兼容性问题...所以不敢全部用正则表达式.
   
0 请登录后投票
最后更新时间:2004-11-26
正则表达式还会不一样? 不都是一个标准么?

[code:1]
public class RegexpFieldValidator extends FieldValidatorSupport {
    private String expression;

    public void validate(Object object) throws ValidationException {
        String fieldName = getFieldName();
        Object value = this.getFieldValue(fieldName, object);
        // if there is no value - don't do comparison
        // if a value is required, a required validator should be added to the field       
        if (value == null)
            return;
        if (!(value instanceof String) || !((String) value).matches(expression)) {
            addFieldError(fieldName, object);
        }
    }

    public String getExpression() {
        return expression;
    }

    public void setExpression(String expression) {
        this.expression = expression;
    }
}
[/code:1]

扩展一下, 就具备了客户端校验的能力了:

[code:1]
public class JavaScriptRegexpFieldValidator extends RegexpFieldValidator implements ScriptValidationAware {
    public String validationScript(Map parameters) {
        String field = (String) parameters.get("name");
        StringBuffer js = new StringBuffer();
       
        js.append("value = form.elements['" + field + "'].value;\n");
        js.append("if (value != \"\" && !value.match(/" + getExpression() + "/)) {\n");
        js.append("\talert('" + getMessage(null) + "');\n");
        js.append("\treturn '" + field + "';\n");
        js.append("}\n");
        js.append("\n");

        return js.toString();
    }

}
[/code:1]
   
0 请登录后投票
最后更新时间:2004-11-26
应该有不一样的东西 微软总是喜欢搞点不一样的东西

这种表达式的方法可能只能检测格式,检测范围可能做不到吧.


我原来的邮件,网址,26个字符,日期类型等都是用正则表达式检测的

另:我参考了一些struts使用的方法的函数
   我想struts没全使用正则表达式也有一些道理吧(我没研究过)
   
0 请登录后投票
最后更新时间:2004-11-30
多谢 scud, 这正是 webwork 所欠缺的,希望能看到下文。

正则表达式好像没什么标准,perl做的比较强所以都照着做,至于做到什么程度,恐怕是各有不同。另外,正则表达式比较适合对格式的检测和取样,其他的就要结合脚本了。
   
0 请登录后投票
论坛首页 Java版 Webwork

跳转论坛:
JavaEye推荐