当前位置: 移动技术网 > IT编程>开发语言>Java > java validation 后台参数验证的使用详解

java validation 后台参数验证的使用详解

2019年07月19日  | 移动技术网IT编程  | 我要评论

一、前言

在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节。比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间、成本、质量的博弈中必然会落后。所以把校验层抽象出来是必然的结果,下面说下几种解决方案。

二、几种解决方案

1、struts2的valid可以通过配置xml,xml中描述规则和返回的信息,这种方式比较麻烦、开发效率低,不推荐

2、validation bean 是基于jsr-303标准开发出来的,使用注解方式实现,及其方便,但是这只是一个接口,没有具体实现.hibernate validator是一个hibernate独立的包,可以直接引用,他实现了validation bean同时有做了扩展,比较强大 ,实现图如下:

3、oval 是一个可扩展的java对象数据验证框架,验证的规则可以通过配置文件、annotation、pojos 进行设定。可以使用纯 java 语言、javascript 、groovy 、beanshell 等进行规则的编写,本次不过多讲解

三、bean validation 框架验证介绍

bean validation 包放在maven上维护,最新包的坐标如下:

<dependency>

  <groupid>javax.validation</groupid>

  <artifactid>validation-api</artifactid>

  <version>1.1.0.final</version>

</dependency> 

下载之后打开这个包,有个package叫constraints,里面放的就是验证的的注解:

  

下面开始用代码实践一下:

1、定义一个待验证的bean:student.java

package com.shishang;

import javax.validation.constraints.*;
import java.io.serializable;
import java.math.bigdecimal;
import java.util.date;

public class student implements serializable {


  @notnull(message = "名字不能为空")
  private string name;

  @size(min = 6,max = 30,message = "地址应该在6-30字符之间")
  private string address;

  @decimalmax(value = "100.00",message = "体重有些超标哦")
  @decimalmin(value = "60.00",message = "多吃点饭吧")
  private bigdecimal weight;

  private string friendname;
  @asserttrue
  private boolean ishavefriend(){
    return friendname != null?true:false;
  }

  @future(message = "生日必须在当前实践之前")
  private date birthday;

  @pattern(regexp = "^(.+)@(.+)$",message = "邮箱的格式不合法")
  private string email;


  public string getname() {
    return name;
  }

  public void setname(string name) {
    this.name = name;
  }

  public string getaddress() {
    return address;
  }

  public void setaddress(string address) {
    this.address = address;
  }

  public bigdecimal getweight() {
    return weight;
  }

  public void setweight(bigdecimal weight) {
    this.weight = weight;
  }

  public string getfriendname() {
    return friendname;
  }

  public void setfriendname(string friendname) {
    this.friendname = friendname;
  }

  public date getbirthday() {
    return birthday;
  }

  public void setbirthday(date birthday) {
    this.birthday = birthday;
  }

  public string getemail() {
    return email;
  }

  public void setemail(string email) {
    this.email = email;
  }
}

2、测试类:studenttest.java

package com.use;

import javax.validation.constraintviolation;
import javax.validation.validation;
import javax.validation.validator;
import javax.validation.validatorfactory;
import java.io.serializable;
import java.math.bigdecimal;
import java.util.arraylist;
import java.util.date;
import java.util.list;
import java.util.set;

public class studenttest implements serializable {
  public static void main(string[] args) {
    student xiaoming = getbean();
    list<string> validate = validate(xiaoming);
    validate.foreach(row -> {
      system.out.println(row.tostring());
    });

  }

  private static student getbean() {
    student bean = new student();
    bean.setname(null);
    bean.setaddress("北京");
    bean.setbirthday(new date());
    bean.setfriendname(null);
    bean.setweight(new bigdecimal(30));
    bean.setemail("xiaogangfan163.com");
    return bean;
  }

  private static validatorfactory factory = validation.builddefaultvalidatorfactory();

  public static <t> list<string> validate(t t) {
    validator validator = factory.getvalidator();
    set<constraintviolation<t>> constraintviolations = validator.validate(t);

    list<string> messagelist = new arraylist<>();
    for (constraintviolation<t> constraintviolation : constraintviolations) {
      messagelist.add(constraintviolation.getmessage());
    }
    return messagelist;
  }
}

3、运行testvalidation()方法,输处如下:

  1. 地址应该在6-30字符之间
  2. 邮箱的格式不合法
  3. 生日必须在当前时间之前
  4. 多吃点饭吧
  5. 名字不能为空

4、总结

  1. 像@notnull、@size等比较简单也易于理解,不多说
  2. 因为bean validation只提供了接口并未实现,使用时需要加上一个provider的包,例如hibernate-validator
  3. @pattern 因为这个是正则,所以能做的事情比较多,比如中文还是数字、邮箱、长度等等都可以做
  4. @asserttrue 这个与其他的校验注解有着本质的区别,这个注解适用于多个字段。例子中ishavefriend方法依赖friendname字段校验
  5. 验证的api是经过我加工了一下,这样可以批量返回校验的信息
  6. 有时我们需要的注解可能没有提供,这时候就需要自定义注解,写实现类,下面说一下自定义注解的使用

四、自定义bean validation 注解验证

有时框架自带的没法满足我们的需求,这时就需要自己动手丰衣足食了,恩恩 ,这个不难,下面说下。

这个例子验证字符串是大写还是小写约束标注,代码如下:

1、枚举类型casemode, 来表示大写或小写模式

 package com.defineconstrain;

/**
 * created by xiaogangfan
 * on 16/10/25.
 */
public enum casemode {
  upper,
  lower;
}

2、定义一个checkcase的约束标注

package com.defineconstrain;

/**
 * created by xiaogangfan
 * on 16/10/25.
 */
import static java.lang.annotation.elementtype.*;
import static java.lang.annotation.retentionpolicy.*;

import java.lang.annotation.documented;
import java.lang.annotation.retention;
import java.lang.annotation.target;

import javax.validation.constraint;
import javax.validation.payload;

@target( { method, field, annotation_type })
@retention(runtime)
@constraint(validatedby = checkcasevalidator.class)
@documented
public @interface checkcase {

  string message() default "{com.mycompany.constraints.checkcase}";

  class<?>[] groups() default {};

  class<? extends payload>[] payload() default {};

  casemode value();

}

3、约束条件checkcase的验证器

package com.defineconstrain;

/**
 * created by xiaogangfan
 * on 16/10/25.
 */
import javax.validation.constraintvalidator;
import javax.validation.constraintvalidatorcontext;

public class checkcasevalidator implements constraintvalidator<checkcase, string> {

  private casemode casemode;

  public void initialize(checkcase constraintannotation) {
    this.casemode = constraintannotation.value();
  }

  public boolean isvalid(string object, constraintvalidatorcontext constraintcontext) {

    if (object == null)
      return true;

    if (casemode == casemode.upper)
      return object.equals(object.touppercase());
    else
      return object.equals(object.tolowercase());
  }

}

4、在student.java中增加一个属性

@checkcase(value = casemode.lower,message = "名字的拼音需要小写")
private string spellname;

5、在studenttest.java的getbean()方法中增加一行

bean.setspellname("xiaogangfan");

6、运行testvalidation()方法,输处如下:

  1. 地址应该在6-30字符之间
  2. 邮箱的格式不合法
  3. 生日必须在当前时间之前
  4. 多吃点饭吧
  5. 名字的拼音需要小写
  6. 名字不能为空

7、说明新增的约束生效了,大功告成

代码下载地址:git@github.com:xiaogangfan/vaidation.git

命令: git clone git@github.com:xiaogangfan/vaidation.git

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网