在项目过程中,通常都需要验证一下用户输入的值是否合法,如何将验证做的更加人性化,更加符合用户的操作习惯则是我们需要讨论的问题。
以我当前维护的一段基于Struts1.x的J2EE项目代码为例,说明一下优秀的验证跟烂验证给用户带来的体验。
目标:在名为industryName的Text输入框内输入10-40个字符
改造前的代码:
2 * Method validate 输入验证
3 * @param mapping
4 * @param request
5 * @return ActionErrors
6 */
7 public ActionErrors validate(ActionMapping mapping,
8 HttpServletRequest request) {
9 log.info("IndustryMainForm.validate() begin");
10 ActionErrors errors = null;
11 // 行业圈名称非空验证
12 if(CommonUtility.isNull(industryName)){
13 if(errors == null)
14 errors = new ActionErrors();
15 log.info("IndustryMainForm.validate() :(行业圈名称非空)校验失败");
16 errors.add("industry", new ActionMessage("information.operationerror"));
17 // 保存用户参数
18 request.setAttribute("industryMainForm", this);
19 }
20
21 // 行业圈名称长度验证
22 if(industryName.length() > 40 || industryNam.length() < 10){
23 if(errors == null)
24 errors = new ActionErrors();
25 log.info("IndustryMainForm.validate() end :(行业圈名称长度)校验失败");
26 errors.add("industry", new ActionMessage("information.operationerror"));
27 // 保存用户参数
28 request.setAttribute("industryMainForm", this);
29 }
30
31 log.info("IndustryMainForm.validate() end");
32 return errors;
33 }
34
说明一下:information.operationerror是属于国际化的内容,意思就是提示四个字“操作失败”
对于这段代码,要求的目标达到了没有?达到了。
但是,给用户带来的后果却是:用户没有输入,页面提示他“操作失败”,聪明的用户可能会估摸着这个应该就是没有输入造成的,行,我输入三五个字,结果还是“操作失败”四个大字放那儿。这用户很聪明,又估摸着这字数可能是太少了,那行,我多复制几次输入进去。一不小心,复制的字数超过了40个字,丫的,又来了一“操作失败”。再怎么聪明的用户,也会觉得这个不应该是他输入的原因了。
其实,之所以用户提交数据不能通过验证,还是他输入的内容有问题。但是页面没有提示他具体的问题点是什么。这好比我让你去黄兴路步行街去找一个外号叫做熊猫的人,在你不认识这个熊猫的时候,你也许会举个大牌子写着“熊猫,有人找你”或者拿着个大喇叭去喊,或者说一个一个的人去问---------当然,这是一种效率极其低下而且需要脸皮比较厚的做法。更加简单的做法是问清楚:那个叫做熊猫的家伙穿着个什么样的衣服,相片,以及他一般什么时候出现在哪个店子。即使是守株待兔也比那个要好。
因此,验证其实跟写代码一样,其实也是需要动动脑子的。
改造后的代码如下:
* Method validate 输入验证
* @param mapping
* @param request
* @return ActionErrors
*/
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
log.info("IndustryMainForm.validate() begin");
ActionErrors errors = new ActionErrors();
// 行业圈名称非空验证
if(CommonUtility.isNull(industryName)){
log.info("IndustryMainForm.validate() :(行业圈名称非空)校验失败");
errors.add("industry", new ActionMessage("errors.required",
CommonUtility.getResourcesMsg(request, "Industry.Main.Name")));
}
if ( errors != null){
// 保存用户参数
request.setAttribute("industryMainForm", this);
return errors;
}
// 行业圈名称长度验证
if (industryName.length() < 10)
log.info("IndustryMainForm.validate() end :(行业圈名称长度下限)校验失败");
errors.add("industry", new ActionMessage("errors.minlength",
CommonUtility.getResourcesMsg(request,
"Industry.Main.Name"),"10"));
} else if(industryName.length() > 40){
log.info("IndustryMainForm.validate() end :(行业圈名称长度上限)校验失败");
errors.add("industry", new ActionMessage("errors.maxlength",
CommonUtility.getResourcesMsg(request,
"Industry.Main.Name"),"40"));
}
if ( errors != null){
// 保存用户参数
request.setAttribute("industryMainForm", this);
return errors;
}
log.info("IndustryMainForm.validate() end");
return errors;
}
如此一来,用户在使用的时候,就能够很清楚的知道,自己为什么输入的东西没有通过验证,很明白应该怎样去修改。
总结下:
其实在做validate验证的时候,是可以写几个私有方法,分成几步来进行的。参照我改造后的代码:
第一步:判断是否为空,可以写一个私有方法checkRequired;
第二步:判断长度是否符合要求,可以写一个私有方法CheckLength;
第三步:判断输入格式是否合法,可以写一个私有方法CheckFormat;
每个方法在执行完毕之后判断是否ActionErrors是否为空,为空则返回页面提示用户。这样做的话,验证逻辑会比较清晰。另外,验证消息还是需要写清楚,否则验证逻辑再清楚,用户也不清楚你需要表达的意思是什么。