-
实现一个可设备的java web 参数验证器
添加时间:2013-7-15 点击量:当应用java web的servlet来供给接口的时辰,若是严格一点,经常会对恳求参数做一些验证并返回错误码。我发明凡是参数验证的代码就在servlet里边,若是参数不正确就返回响应的错误码。若是接口数量少,参数不久不多还没什么感触感染。若是参数多了,那么可能验证参数的代码就会有一大堆,显得非分希罕乱。接口数量多了,那工作量也是很是的重大。其实参数验证是一件反复的工作,不合的接口对参数的验证根蒂根基是一样的,无非就是验证一下参数是否为空,是否合适指定格局。
如许就可以将参数验证的逻辑提取出来,不放在servlet里,若是参数验证错误将直接返回错误码,都不消经过servlet处理惩罚。说到这里就想到了filter,filter可以将恳求做一下过滤,若是没题目再转交给servlet处理惩罚,servlet直接大胆的提取参数用即可,底子不消愁闷参数的错误题目。那不合的接口有不合的验证参数,filter怎么知道该验证哪个接口的哪个参数呢,又是怎么知道这个参数该合适什么样的格局呢?那就想到了listener,listener在法度启动时运行,我们可以将接口及验证参数和验证格局设备到xml文件中,法度启动时读取xml文件。恳求到来时,filter读取listener事先收拾好的接口验证器进行验证即可。
接下来先看一下参数验证的xml:
<validators xmlns=http://www.example.net/test xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation=http://www.example.net/test validateParam.xsd>
<servletValidator servletUrl=/RecordLogInInfo>
<validator validatorClass=com.validator.RegexValidator pattern=[0-9]+>
<validateParam name=userid errorCode=0104102 />
</validator>
<validator validatorClass=com.validator.NullValidator>
<validateParam name=userid errorCode=0104101 />
<validateParam name=phoneos errorCode=0104103 />
<validateParam name=devicename errorCode=0104104 />
</validator>
</servletValidator>
</validators>Validators代表跟元素,servletValidator 代表对应servlet的参数验证器,servlet有几许就有几许servletValidator 。servletUrl代表servlet的url映射。然后里边有若干个validator,每个validator对应一个功能参数验证器,不合的validator有不合的功能。validatorClass代表验证器的class,validator的子标签validateParam 代表这个验证器验证的参数及错误码。上边的例子是一个记录客户端登录信息的接口,userid不克不及为空(对应错误码0104101)且只能是数字(对应错误码0104102)。Phoneos、devicename不克不及为空,也有其对应的错误码。
如上所示NullValidator负责验证参数是否为空,有几许种参数验证功能我们只须要供给几许种validator即可,例如取值局限在1、2、3、4之间的,是否为大于某一个整数的,是否为字符’,’隔开的字符串。有几许种验证体式格式就供给几许validator是不是太麻烦了呢,确切是如许。幸好大多半的验证都是可以经由过程正则表达式来验证的。如许我们就省下了很多的工作量,如RegexValidator就是一个正则表达式验证器,只要正则表达式能默示的就可以用这个验证器。
那我们的验证器应当怎么来写呢。我们有一个抽象的validator:
public abstract class AbstractParamValidator {
protected Map<String, String> paramsMap = new HashMap();
public void addParam(String paramName, String errorCode) {
this.paramsMap.put(paramName, errorCode);
}
public List<String> validate(HttpServletRequest req) throws Exception {
List errorCodes = new ArrayList();
for (String paramName : this.paramsMap.keySet()) {
if (isError(req.getParameter(paramName))) {
errorCodes.add((String) this.paramsMap.get(paramName));
}
}
return errorCodes;
}
protected abstract boolean isError(String paramString) throws Exception;
}本身定义的validator只须要持续自这个抽象类并实现isError即可。比如RegexValidator:
public class RegexValidator extends AbstractParamValidator {
private String pattern=null;
@Override
protected boolean isError(String content) throws Exception {
return StringUtil.isNotNull(content)&&!content.matches(pattern);
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
}此中pattern就是我们在xml设备中设备的,值得重视的是也要有一个标准的set办法与之对应,并且不管是什么类型,set办法只接管string类型参数,若是须要转换成其他类型则在办法里进行转换就好了。当然每个验证器须要的前提是不一样的,按照本身的须要来设备就好了,名字对就行了,当然也可以设备多个。
验证器写完了,下一步来看一下listener是怎么实现的。起首我们有一个全局的Map<String, List<AbstractParamValidator>>,在listener里遍历xml的servletValidator 并遍历servletValidator 里的validator ,哄骗反射将validator 实例化,再遍历validator 里的validateParam 并调用addParam办法将参数及错误码添加到validator 参数列表中。(具体代附在最后共查看)。
下边就是filter了,filter按照恳求的url取出对应的验证器列表进行验证,并返回错误码。(具体代附在最后共查看)
剩下的就很简单了,在web.xml中设备listener和filter即可。当然也可以在listener中动态注册filter,然则这要用到servlet-api.jar在tomcat中没啥题目。若是是用jetty办事器,那么jetty带的servlet-api.jar就不必然有动态注册的filter的办法了。
有什么错误还请大师斧正。
附件,反编译一下就好了,参数验证jar包