实现一个可设备的java web 参数验证器

    添加时间:2013-7-15 点击量:

      当应用java webservlet来供给接口的时辰,若是严格一点,经常会对恳求参数做一些验证并返回错误码。我发明凡是参数验证的代码就在servlet里边,若是参数不正确就返回响应的错误码。若是接口数量少,参数不久不多还没什么感触感染。若是参数多了,那么可能验证参数的代码就会有一大堆,显得非分希罕乱。接口数量多了,那工作量也是很是的重大。其实参数验证是一件反复的工作,不合的接口对参数的验证根蒂根基是一样的,无非就是验证一下参数是否为空,是否合适指定格局。


      如许就可以将参数验证的逻辑提取出来,不放在servlet里,若是参数验证错误将直接返回错误码,都不消经过servlet处理惩罚。说到这里就想到了filterfilter可以将恳求做一下过滤,若是没题目再转交给servlet处理惩罚,servlet直接大胆的提取参数用即可,底子不消愁闷参数的错误题目。那不合的接口有不合的验证参数,filter怎么知道该验证哪个接口的哪个参数呢,又是怎么知道这个参数该合适什么样的格局呢?那就想到了listenerlistener在法度启动时运行,我们可以将接口及验证参数和验证格局设备到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代表servleturl映射。然后里边有若干个validator,每个validator对应一个功能参数验证器,不合的validator有不合的功能。validatorClass代表验证器的classvalidator的子标签validateParam 代表这个验证器验证的参数及错误码。上边的例子是一个记录客户端登录信息的接口,userid不克不及为空(对应错误码0104101)且只能是数字(对应错误码0104102)。Phoneosdevicename不克不及为空,也有其对应的错误码。


      如上所示NullValidator负责验证参数是否为空,有几许种参数验证功能我们只须要供给几许种validator即可,例如取值局限在1234之间的,是否为大于某一个整数的,是否为字符’,’隔开的字符串。有几许种验证体式格式就供给几许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里遍历xmlservletValidator 并遍历servletValidator 里的validator ,哄骗反射将validator 实例化,再遍历validator 里的validateParam 并调用addParam办法将参数及错误码添加到validator 参数列表中。(具体代附在最后共查看)。


      下边就是filter了,filter按照恳求的url取出对应的验证器列表进行验证,并返回错误码。(具体代附在最后共查看)


      剩下的就很简单了,在web.xml中设备listenerfilter即可。当然也可以在listener中动态注册filter,然则这要用到servlet-api.jartomcat中没啥题目。若是是用jetty办事器,那么jetty带的servlet-api.jar就不必然有动态注册的filter的办法了。


      有什么错误还请大师斧正。


     附件,反编译一下就好了,参数验证jar包


    文艺不是炫耀,不是花哨空洞的文字堆砌,不是一张又一张的逆光照片,不是将旅行的意义转化为名牌包和明信片的物质展示;很多时候它甚至完全不美——它嘶吼、扭曲,它会痛苦地抽搐,它常常无言地沉默。——艾小柯《文艺是一种信仰》
    分享到: