validation 后台参数验证
在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节。比如参数不能为null,email邮件必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间、成本、质量的博弈中必然会落后。所以把校验层抽象出来是必然的结果,下面说下几种解决方案。
validation bean 是基于JSR-303标准开发出来的,使用注解方式实现,极其方便,但是这只是一个接口,没有具体实现.Hibernate Validator是一个hibernate独立的包,可以直接引用,他实现了validation bean同时有做了扩展,比较强大 ,实现图如下:
bean validation 框架验证介绍
bean validation 包放在maven上维护,最新包的坐标如下:
1
2
3
4
5
|
< dependency >
< groupId >javax.validation</ groupId >
< artifactId >validation-api</ artifactId >
< version >1.1.0.Final</ version >
</ dependency >
|
下面是个测试案例:
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;
}
}
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;
}
}
运行结果:
地址应该在6-30字符之间
邮箱的格式不合法
生日必须在当前时间之前
多吃点饭吧
名字不能为空
总结 - 像@NotNull、@Size等比较简单也易于理解,不多说
- 因为bean validation只提供了接口并未实现,使用时需要加上一个provider的包,例如hibernate-validator
- @Pattern 因为这个是正则,所以能做的事情比较多,比如中文还是数字、邮箱、长度等等都可以做
- @AssertTRue 这个与其他的校验注解有着本质的区别,这个注解适用于多个字段。例子中isHaveFriend方法依赖friendName字段校验