java bean validation 参数验证
一、前言
在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节。比如参数不能为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()方法,输处如下:
地址应该在6-30字符之间
邮箱的格式不合法
生日必须在当前时间之前
多吃点饭吧
名字不能为空
4、总结
- 像@NotNull、@Size等比较简单也易于理解,不多说
- 因为bean validation只提供了接口并未实现,使用时需要加上一个provider的包,例如hibernate-validator
- @Pattern 因为这个是正则,所以能做的事情比较多,比如中文还是数字、邮箱、长度等等都可以做
- @AssertTRue 这个与其他的校验注解有着本质的区别,这个注解适用于多个字段。例子中isHaveFriend方法依赖friendName字段校验
- 验证的api是经过我加工了一下,这样可以批量返回校验的信息
- 有时我们需要的注解可能没有提供,这时候就需要自定义注解,写实现类,下面说一下自定义注解的使用
四、自定义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()方法,输处如下:
地址应该在6-30字符之间
邮箱的格式不合法
生日必须在当前时间之前
多吃点饭吧
名字的拼音需要小写
名字不能为空
7、说明新增的约束生效了,大功告成
代码下载地址:git@github.com:xiaogangfan/vaidation.git
命令: git clone git@github.com:xiaogangfan/vaidation.git
java bean validation 参数验证的更多相关文章
- 深入了解数据校验:Java Bean Validation 2.0(JSR380)
每篇一句 吾皇一日不退役,尔等都是臣子 相关阅读 [小家Java]深入了解数据校验(Bean Validation):基础类打点(ValidationProvider.ConstraintDescri ...
- Java中的参数验证(非Spring版)
1. Java中的参数验证(非Spring版) 1.1. 前言 为什么我总遇到这种非正常问题,我们知道很多时候我们的参数校验都是放在controller层的传入参数进行校验,我们常用的校验方式就是引入 ...
- Java bean validation 规范与参考实现
1.Apache Bval 依赖包:validation-api-1.1.0.Final.jar org.apache.bval.bundle-1.1.1.jar bval-core-1.1.1.ja ...
- Java Bean Validation(参数校验) 最佳实践
转载来自:http://www.cnblogs.com 参数校验是我们程序开发中必不可少的过程.用户在前端页面上填写表单时,前端js程序会校验参数的合法性,当数据到了后端,为了防止恶意操作,保持程序的 ...
- Java Bean Validation 最佳实践
参数校验是我们程序开发中必不可少的过程.用户在前端页面上填写表单时,前端js程序会校验参数的合法性,当数据到了后端,为了防止恶意操作,保持程序的健壮性,后端同样需要对数据进行校验.后端参数校验最简单的 ...
- SpringBoot - Bean validation 参数校验
目录 前言 常见注解 参数校验的应用 依赖 简单的参数校验示例 级联校验 @Validated 与 @Valid 自定义校验注解 前言 后台开发中对参数的校验是不可缺少的一个环节,为了解决如何优雅的对 ...
- JSR 303 - Bean Validation 模型验证
类是转载的,不知道转的哪里的. 此类依赖 JSR 303 – Bean Validation, Hibernate Validator. 代码不能直接运行.意会一下.自己改改. import com. ...
- Validation参数验证
在SpringBoot项目中其实已经默认引入了,如果不是sprongBoot项目则需要导入Maven <dependency> <groupId>org.hibernate.v ...
- Java Bean validation specification...
http://www.ibm.com/developerworks/cn/java/j-lo-beanvalid/index.html
随机推荐
- PHP中汉字截取
$len = 19; $text = "怎么将新闻的很长的标题只显示前面一些字,后面用.....来代替?"; echo strlen($text)<=$len ? $text ...
- day06-三元表达式
python中没有其他语言中的三元表达式,不过有类似的实现方法 其他语言中,例如java的三元表达式是这样int a = 1;String b = "";b = a > 1? ...
- MySQL5.7 查询用户,配置IP限制
1) MySQL 查询现在所有用户 select host,user from user; Navicat点击用户标签 查询;2) GRANT ALL PRIVILEGES ON *.* TO 'em ...
- 网易云音乐api资料
https://github.com/LanFD/music_163 网易云音乐常用API浅析:http://moonlib.com/606.html
- 虚拟机扩容mac
VMware虚拟机Mac增大容量: 1.设置硬盘容量大小 2.打开虚拟机的终端,找到需要扩展的硬盘.输入命令 :diskutil list 注意 :我的硬盘名字叫yz,这一行可以看见当前分配容量,最后 ...
- Netty - 3 内存分配
https://www.cnblogs.com/gaoxing/p/4253833.html netty的buffer引入了缓冲池.该缓冲池实现使用了jemalloc的思想 内存分配是面向虚拟内存的而 ...
- C++ AfxBeginThread和AfxEndThread 使用方法
启动线程: CWinThread* AfxBeginThread( 线程函数,this ); 线程的退出: 在刚刚使用的时候,退出线程的方法有问题,导致退出的时候异常. 下面说线程退出的方法: 1. ...
- pandas库的数据类型运算
pandas库的数据类型运算 算数运算法则 根据行列索引,补齐运算(不同索引不运算,行列索引相同才运算),默认产生浮点数 补齐时默认填充NaN空值 二维和一维,一维和0维之间采用广播运算(低维元素与每 ...
- MongoDB常用查询,排序,group,SpringDataMongoDB update group
MongoDB查询 指定查询并排序 db.getCollection('location').find({"site.id":"川A12345","s ...
- js高级-函数变量提升
var a = 10; function f1(){ console.log(a) //undefined 函数变量提升了 函数执行之前想创建了函数的EC 把函数里面声明的变量初始化undefine ...