论坛首页 Java版 Webwork

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

浏览 14919 次
该帖已经被评为精华帖
作者 正文
时间:2004-11-26
已有但不采用的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-26
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推荐