浏览 4889 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-09-13
下面是我的一些想法,不知道合不合适,请大家讨论一下:^_^ 在现在的应用中有很多需要验证页面输入的内容是不是空、是不是数字、是不是Double、是不是Int、是不是Float、是不是Email格式、是不是电话格式、是不是邮政编码格式等等验证,在编码中不得不对每一个属性进行验证,这些代码都重复的。因此,如果将这些验证的代码放到一个父类中,那么将会减少编写的代码良,同时也能够很好的对验证的格式做出一个调整。比如说如果验证中国的邮政编码的格式改为验证其他国家的邮政编码,只需要修改配置文件中的邮政编码的正则表达式即可,不用修改代码。下面是实现的一些分析: 1. 从Properties文件中读取配置文件的类: 将数字、Email、电话和邮政编码等的格式的正则表达式写在一个properties文件中,便于修改。其regex .properties文件的内容如下: numberRegex ="\\d" emailRegex = "\\S+@\\S+\\.\\S+" postCodeRegex =" \\d\\d\\d\\d\\d" ……………… 在程序中使用如下代码进行匹配邮政编码的格式: protected boolean isValidPostalCode(String str){ try{ Pattern pattern = Pattern.compile( //从properties文件里读入邮政编码格式的正则表达式 PropertyReader.getValueByKey(Constants.POSTAL_CODE)); //进行匹配,返回结果 return pattern.matcher(str).matches(); }catch(Exception e){ return false; } } 其他验证均是如此。此外改方法式protected的方法,可以被子类覆盖、调用。 2. 其他一些验证方法: a) 验证字符串是否为空的函数: protected boolean isBlankString(String str){ if(str == null) { return true; } return (str.length() == 0); } b) 验证输入内容式Double类型的函数: protected boolean isDouble(String str){ try{ Double.parseDouble(str); return true; }catch(Exception e){ return false; } } 其他验证Float、Int类型的函数同Double类型的函数一样,没有什么区别。同样他们都是protected的函数,可以被子类覆盖,调用。 3. 覆盖validate()方法: public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); ActionErrors tempErrors = null; //----------------------------------------------------- //Validate required! ///验证输入内容必须输入的属性的函数 //----------------------------------------------------- tempErrors = validateRequired(); if(tempErrors != null){ errors.add(tempErrors); } //----------------------------------------------------- //Validate postal code! //----------------------------------------------------- tempErrors = validatePostalCode(); if(tempErrors != null){ errors.add(tempErrors); } //----------------------------------------------------- //Validate double! //----------------------------------------------------- tempErrors = validateDouble(); if(tempErrors != null){ errors.add(tempErrors); } //----------------------------------------------------- //Validate phone! //----------------------------------------------------- tempErrors = validatePhone(); if(tempErrors != null){ errors.add(tempErrors); } //----------------------------------------------------- //Validate state! //----------------------------------------------------- tempErrors = validateState(); if(tempErrors != null){ errors.add(tempErrors); } //----------------------------------------------------- //Validate email! //----------------------------------------------------- tempErrors = validateEmail(); if(tempErrors != null){ errors.add(tempErrors); } ……………………………… ……………………………… ……………………………… ……………………………… ……………………………… ……………………………… //----------------------------------------------------- //Validate Others //可以实现自己与众不同的验证,返回一个ActionErrors对象。 //----------------------------------------------------- tempErrors = validateOthers(mapping,request); if(tempErrors != null){ errors.add(tempErrors); } return errors; } 在该函数里面依次调用验证不能为空的验证方法,必须式Email格式等等的验证函数,最后一个validateOthers()是protected函数,可以被子类覆盖,在子类中实现上面没有实现的验证,然后在将验证的结果ActionErrors对象返回即可。 4. validateRequired()函数的实现: /** * Validate required! *验证必须输入的属性 * @return ActionErrors */ private ActionErrors validateRequired(){ //初始化一个ActionErrors对象 ActionErrors errors = new ActionErrors(); //读取需要进行必须验证的属性列表 List properties = getRequiredPropertyList(); String propertyName = ""; String propertyValue = ""; if((properties != null)&&(properties.size()>0)){ //依次对需要验证的属性进行验证 for(int i = 0;i<properties.size();i++){ //获取属性名的字符串 propertyName = (String)properties.get(i); //获取对应属性的输入值 propertyValue = (String)getTheValue(propertyName); //验证属性值是否为空 if(this.isBlankString(propertyValue)){ //在Struts的资源文件中定义出错提示信息 //以“属性名”为“key”将错误信息添加到errors中去。 errors.add(propertyName,new ActionMessage("stocktrack.newuser.required",propertyName)); } } } //返回结果 return errors; } getRequiredPropertyList()是获取必须验证属性列表的函数。该函数的定义如下: protected List getRequiredPropertyList(){ return null; } 可见该函数是一个protected的函数,需要子类覆盖。在子类中需要将要进行必须验证的属性名添加到一个List中去,然后将List返回。下面是一个实现的例子: public List getRequiredPropertyList() { List list = new ArrayList(); list.add("username"); list.add("password"); list.add("email"); list.add("streetAddress1"); list.add("streetAddress2"); list.add("city"); list.add("state"); list.add("postalCode"); list.add("homePhone"); list.add("workPhone"); return list; } 这里的属性名必须与Form类中的属性名相同。 讨论:这里最初的想法是将getRequiredPropertyList()这一类方法定义成为一个抽象(abstract)方法,这样子类中就必须实现改方法,避免忘记实现。但是在一些Form中也不一定都会要验证所有的内容,但是程序员也必须实现那些方法,而且他们实现也是返回null即可。如果在BaseForm类中实现了就不用做这种无用的事情了。请给予指正! ――――――――――――――――――――――――――――――――― getTheValue(propertyName)方法是用来通过传进去的属性名取出该属性对应的属性值,下面是改方法的实现: private Object getTheValue(String property){ Object object = null; Method method = null; Class clazz = null; String methodName = ""; //如果属性名为空,则返回null if(isBlankString(property)){ return null; } //将属性名的第一个字母大写,然后加上get构成属性对应的get方法//名。 //注意:这里的属性名的第一个字符必须是字母,否则会出错。(请 //讨论) methodName = "get" + property.substring(0,1).toUpperCase() + property.substring(1,property.length()); //从methodsMap(存放方法的一个Map)里面取方法 method = (Method) methodsMap.get(methodName); if(method == null){ //如果methodsMap中不存在方法名,则通过反射得到方法 //获取该类的Class对象 clazz = getClass(); try { //通过反射获取属性名对应的get方法 method = clazz.getMethod(methodName, new Class[0]); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } //这里以方法名为key将获取的方法放到methodsMap中,以便 //下次使用的时候不用使用反射。 methodsMap.put(methodName,method); } try { //运行方法,获取属性值 object = method.invoke(this,new Object[0]); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } //将属性值返回 return object; } 5. 继承BaseForm之后需要做的事情: 1)添加属性(必须是String型,属性名的第一个字符必须是字母); 2)将需要验证的属性添加到对应的List方法中,然后返回List; 3)如果有没有实现的验证,请覆validateOthers()方法,该方法和普通的validate方法没有不同之处。 6. 没有实现的内容: 属性是数组的情况没有考虑,如果有属性是数组的情况,请自己实现validateOthers方法。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2005-09-13
引用 //在Struts的资源文件中定义出错提示信息 //以“属性名”为“key”将错误信息添加到errors中去。 errors.add(propertyName,new ActionMessage("stocktrack.newuser.required",propertyName)); 一般说来每个属性对应的"Key"应该是不同吧? |
|
返回顶楼 | |
发表时间:2005-09-13
提点看法:
1,感觉是对几种常用验证的一种封装. 2, getRequiredPropertyList() 需要在代码中配置这些, 对应还有getEmailPropertyList(),getMaxPropertyList()... 等等的方法吧, 如果同时要验证这个属性是required 和 max,min 的,是否要在三个方法上都 list.add("xxx") 呢? 而且感觉这样很麻烦. 总的来说, 感觉实用不是很好, 我没有感觉到比validation更好的思想和方便性! 或许有些方便的地方我没有理解, 你可以再说清楚一些. |
|
返回顶楼 | |
发表时间:2005-09-13
Morgan0916 写道 引用 //在Struts的资源文件中定义出错提示信息 //以“属性名”为“key”将错误信息添加到errors中去。 errors.add(propertyName,new ActionMessage("stocktrack.newuser.required",propertyName)); 一般说来每个属性对应的"Key"应该是不同吧? 这里“stocktrack.newuser.required”只是我在最开初做的时候用的,我在这里加了一个参数(请输入{0}!)。后面的“propertyName”将参数值传进去。显示出来的是“请输入××!”之类的提示。 |
|
返回顶楼 | |
发表时间:2005-09-13
Morgan0916 写道 提点看法:
1,感觉是对几种常用验证的一种封装. 2, getRequiredPropertyList() 需要在代码中配置这些, 对应还有getEmailPropertyList(),getMaxPropertyList()... 等等的方法吧, 如果同时要验证这个属性是required 和 max,min 的,是否要在三个方法上都 list.add("xxx") 呢? 而且感觉这样很麻烦. 总的来说, 感觉实用不是很好, 我没有感觉到比validation更好的思想和方便性! 或许有些方便的地方我没有理解, 你可以再说清楚一些. ^_^,这个东西是在我没有学validation的时候弄的一个东西。在不用学新的东西的前提下使用这个东西还是可以的。 |
|
返回顶楼 | |