文章目录
1、javaBean hibernate Validation 介绍1.1、注解类型列表1.2、依赖:1.3、(低版本)springboot1.5 + JDK1.7的依赖
2、入门使用( 验证的普通 JavaBean )2.1、要校验的对象2.2、校验工具类2.3、测试
3、自定义校验器3.1、定义校验器接口:3.2、校验器接口的实现:3.3、要验证的对象3.4、测试:
4、hibernate的校验模式4.1、普通模式(默认)4.2、快速失败返回模式4.3、配置
5、SpringBoot 时,将 校验模式对象 添加到容器中
1、javaBean hibernate Validation 介绍
1.1、注解类型列表
JSR303中常用的注解类型
注解类型属性值类型使用说明
@AssertFalseBoolean、boolean被注解的属性值是false。@AssertTrueBoolean、boolean被注解的属性值是true。@MaxBigDecimal、BigInteger、int、longbyte、short 及对应类型的包装类被注解的属性值必须小于或等于指定的最大值。@Min-同上被注解的属性值必须大于或等于指定的最小值。@Negative-同上被注解的属性值必须为负数。@NegativeOrZero-同上被注解的属性值必须为负数或0。@Positive-同上被注解的属性值必须为正数。@PositiveOrZero-同上被注解的属性值必须为正数或0。@Digits(integer=,fraction=)BigDecimal、BigInteger、int、longbyte、short 、String及对应类型的包装类被注解的属性值必须是数字。integer 表示 整数部分最多少位;fraction 表示 小数部分最多保留多少位。@DecimalMin(value)同上被注解的属性值必须是数字,其值必须大于或等于指定的最小值。注:参数值必须是能正确转化为BigDecimal的字符串,即,会使用new BigDecimal(String str)。@DecimalMax(value)同上被注解的属性值必须是数字,其值必须小于或等于指定的最大值。注:参数值必须是能正确转化为BigDecimal的字符串,即,会使用new BigDecimal(String str)@NotBlankString被注解的属性值是否为非null,并且 去空格之后 的length大于0。与@NotEmpty的区别在于,@NotBlank 只能注解 字符串,并且忽略结尾空格。@Size(min=, max=)String、Collection、Map、arrays被注解的属性值大小介于min和max(包含)之间。@NotEmpty同上被注解的属性值是否为 非null 或 空集合。@NotNull任意类型,含对象被注解的属性值是否为非null。@Null任意类型,含对象被注解的属性值是否为null。@Futurejava.util.Date,java.util.Calendar;被注解的属性值必须是将来的一个日期。@FutureOrPresent-同上被注解的属性值必须是当前或将来的一个日期。@Past-同上被注解的属性值必须是过去的一个日期。@PastOrPresent-同上被注解的属性值必须是现在或过去的一个日期。@Pattern(regexp,message)-同上被注解的属性值必须符合指定的正则表达式@EmailString被注解的属性值是Email地址。
Hibernate validator 在JSR303的基础上对校验注解进行了扩展,其中常用的注解如下:
注解类型属性值类型使用说明
@LengthString、Collection、Map、arrays被注解的字符串的长度必须在指定的范围内@RangeString、Collection、Map、arrays被注解的元素必须在合适的范围内
1.2、依赖:
<dependency>
<groupId>junit
</groupId>
<artifactId>junit
</artifactId>
<version>4.12
</version>
<scope>test
</scope>
</dependency>
<dependency>
<groupId>org.apache.commons
</groupId>
<artifactId>commons-lang3
</artifactId>
<version>3.0
</version>
</dependency>
<dependency>
<groupId>javax.validation
</groupId>
<artifactId>validation-api
</artifactId>
<version>2.0.1.Final
</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator
</groupId>
<artifactId>hibernate-validator
</artifactId>
<version>6.0.7.Final
</version>
</dependency>
<dependency>
<groupId>org.glassfish
</groupId>
<artifactId>javax.el
</artifactId>
<version>3.0.1-b08
</version>
</dependency>
<dependency>
<groupId>ch.qos.logback
</groupId>
<artifactId>logback-core
</artifactId>
<version>1.1.8
</version>
</dependency>
<dependency>
<groupId>ch.qos.logback
</groupId>
<artifactId>logback-classic
</artifactId>
<version>1.1.8
</version>
</dependency>
<dependency>
<groupId>org.slf4j
</groupId>
<artifactId>slf4j-api
</artifactId>
<version>1.7.22
</version>
</dependency>
validation-api 是定义的接口,hibernate-validator是接口的实现类,所以,这2个包要配合着使用。
1.3、(低版本)springboot1.5 + JDK1.7的依赖
<dependency>
<groupId>org.hibernate
</groupId>
<artifactId>hibernate-validator
</artifactId>
<version>5.3.5.Final
</version>
</dependency>
<dependency>
<groupId>javax.el
</groupId>
<artifactId>el-api
</artifactId>
<version>2.2
</version>
</dependency>
<dependency>
<groupId>javax.validation
</groupId>
<artifactId>validation-api
</artifactId>
<version>1.1.0.Final
</version>
</dependency>
2、入门使用( 验证的普通 JavaBean )
2.1、要校验的对象
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.2、校验工具类
import java
.util
.ArrayList
;
import java
.util
.List
;
import java
.util
.Set
;
import javax
.validation
.ConstraintViolation
;
import javax
.validation
.Validation
;
import javax
.validation
.Validator
;
import javax
.validation
.ValidatorFactory
;
public class ValidatorModel {
private static ValidatorFactory factory
=Validation
.buildDefaultValidatorFactory();
public static <T> List
<String> getListByValidate(T t
,,Class
<?>... groups
) {
Validator validator
= factory
.getValidator();
Set
<ConstraintViolation
<T>> constraintViolations
= validator
.validate(t
, groups
);
List
<String> messageList
= new ArrayList<>();
for (ConstraintViolation
<T> constraintViolation
: constraintViolations
) {
System
.out
.println(constraintViolation
.getPropertyPath().toString());
System
.out
.println(constraintViolation
.getInvalidValue());
System
.out
.println(constraintViolation
.getMessage());
System
.out
.println("---------");
messageList
.add(constraintViolation
.getMessage());
}
return messageList
;
}
public static <T> List
<String> validate(T t
,String propertyName
) {
Validator validator
= factory
.getValidator();
Set
<ConstraintViolation
<T>> constraintViolations
= validator
.validateProperty(t
, propertyName
);
List
<String> messageList
= new ArrayList<>();
for (ConstraintViolation
<T> constraintViolation
: constraintViolations
) {
System
.out
.println(constraintViolation
.getPropertyPath().toString());
System
.out
.println(constraintViolation
.getInvalidValue());
System
.out
.println(constraintViolation
.getMessage());
System
.out
.println("---------");
messageList
.add(constraintViolation
.getMessage());
}
return messageList
;
}
}
2.3、测试
package com
.aop8
.vaild
;
import java
.math
.BigDecimal
;
import java
.util
.List
;
import org
.junit
.Test
;
public class Main {
@Test
public void test1() throws Exception
{
Student student
= getBean();
List
<String> validate
= validate(student
);
validate
.forEach(row
-> {
System
.out
.println(row
.toString());
});
}
@Test
public void test2() throws Exception
{
Student student
= getBean();
List
<String> validate
= validate(student
,"address");
validate
.forEach(row
-> {
System
.out
.println(row
.toString());
});
}
}
test1() 运行结果:
email
xiaogangfan163.com
邮箱的格式不合法
---------
address
北京
地址应该在6-30字符之间
---------
name
null
名字不能为空
---------
birthday
Sun May 26 09:05:53 CST 2019
生日必须在当前实践之前
---------
weight
30
多吃点饭吧
---------
test2() 运行结果:
address
北京
地址应该在6-30字符之间
---------
3、自定义校验器
自定义一个校验字符串类型的时间,要求值必须是将来的日期。
3.1、定义校验器接口:
import static java
.lang
.annotation
.ElementType
.ANNOTATION_TYPE
;
import static java
.lang
.annotation
.ElementType
.CONSTRUCTOR
;
import static java
.lang
.annotation
.ElementType
.FIELD
;
import static java
.lang
.annotation
.ElementType
.METHOD
;
import static java
.lang
.annotation
.ElementType
.PARAMETER
;
import static java
.lang
.annotation
.ElementType
.TYPE_USE
;
import static java
.lang
.annotation
.RetentionPolicy
.RUNTIME
;
import java
.lang
.annotation
.Documented
;
import java
.lang
.annotation
.Repeatable
;
import java
.lang
.annotation
.Retention
;
import java
.lang
.annotation
.Target
;
import javax
.validation
.Constraint
;
import javax
.validation
.Payload
;
@Target({ METHOD
, FIELD
, ANNOTATION_TYPE
, CONSTRUCTOR
, PARAMETER
, TYPE_USE
})
@Retention(RUNTIME
)
@Repeatable(ListStr
.class)
@Documented
@Constraint(validatedBy
= {FutureStrValidator
.class })
public @
interface FutureStr {
String
message() default "{javax.validation.constraints.FutureStr.message}";
Class
<?>[] groups() default { };
Class
<? extends Payload>[] payload() default { };
@Target({ METHOD
, FIELD
, ANNOTATION_TYPE
, CONSTRUCTOR
, PARAMETER
, TYPE_USE
})
@Retention(RUNTIME
)
@Documented
@
interface ListStr {
FutureStr
[] value();
}
}
3.2、校验器接口的实现:
package com
.aop8
.common
.validation
;
import java
.util
.Date
;
import java
.util
.regex
.Pattern
;
import javax
.validation
.ConstraintValidator
;
import javax
.validation
.ConstraintValidatorContext
;
import com
.aop8
.common
.utils
.DateUtils
;
public class FutureStrValidator implements ConstraintValidator<FutureStr, String> {
private FutureStr futureStr
;
private static String reg
= "(\\d{4}\\-\\d{1,2}\\-\\d{1,2})+";
static Pattern moneyPattern
= Pattern
.compile(reg
);
public void initialize(FutureStr pastStr
) {
}
public boolean isValid(String value
, ConstraintValidatorContext constraintContext
) {
if (value
== null
) {
return false;
}
value
=value
.replaceAll("/", "-");
boolean b1
= moneyPattern
.matcher(value
).matches();
if (!b1
) {
return b1
;
}
Date dateValue
= DateUtils
.dateStrToDate(value
, DateUtils
.DATE_PATTERN
);
if (dateValue
== null
) {
return false;
}
Date now
= DateUtils
.formatByDate(new Date());
if (dateValue
.compareTo(now
) > 0) {
return true;
}
return false;
}
}
一个工具类:
package com
.aop8
.vaild
;
import java
.text
.ParseException
;
import java
.text
.SimpleDateFormat
;
import java
.util
.Date
;
import org
.slf4j
.Logger
;
import org
.slf4j
.LoggerFactory
;
public class DateUtils {
private final static Logger logger
= LoggerFactory
.getLogger(DateUtils
.class);
public final static String DATE_PATTERN
= "yyyy-MM-dd";
public final static String DATE_TIME_PATTERN
= "yyyy-MM-dd HH:mm:ss";
public final static String SHORT_DATE
= "yyyy年MM月dd日";
public static String
format(Date date
) {
return format(date
, DATE_PATTERN
);
}
public static String
format(Date date
, String pattern
) {
if (date
!= null
) {
SimpleDateFormat df
= new SimpleDateFormat(pattern
);
return df
.format(date
);
}
return null
;
}
public static Date
dateStrToDate(String dateStr
, String format
) {
Date d
=null
;
try {
d
= new SimpleDateFormat(format
).parse(dateStr
);
} catch (ParseException e
) {
e
.printStackTrace();
}
return d
;
}
public static Date
formatByDate(Date date
){
SimpleDateFormat formatter
= new SimpleDateFormat(DATE_PATTERN
);
String _dateStr
=formatter
.format(date
);
try {
return formatter
.parse(_dateStr
);
} catch (ParseException e
) {
e
.printStackTrace();
}
return null
;
}
}
3.3、要验证的对象
package com
.aop8
.vaild
;
import java
.io
.Serializable
;
import java
.math
.BigDecimal
;
import java
.util
.Date
;
import javax
.validation
.constraints
.DecimalMax
;
import javax
.validation
.constraints
.DecimalMin
;
import javax
.validation
.constraints
.Digits
;
import javax
.validation
.constraints
.NotBlank
;
import javax
.validation
.constraints
.NotNull
;
import javax
.validation
.constraints
.PastOrPresent
;
import javax
.validation
.constraints
.Positive
;
import org
.hibernate
.validator
.constraints
.Length
;
public class UserVO2 implements Serializable {
@NotNull(message
="规划时间不能为空")
@FutureStr(message
="规划时间必须是将来的一个日期")
private String futerTime
;
public String
getFuterTime() {
return futerTime
;
}
public void setFuterTime(String futerTime
) {
this.futerTime
= futerTime
;
}
}
3.4、测试:
package com
.aop8
.vaild
;
import java
.math
.BigDecimal
;
import java
.util
.List
;
import org
.junit
.Test
;
public class Main {
@Test
public void test2() {
UserVO2 userVO
=new UserVO2();
userVO
.setFuterTime("2019-02-05");
List
<String> list
=ValidatorModel
.getListByValidate(userVO
);
System
.out
.println(list
.toString());
}
}
运行结果:
[规划时间必须是将来的一个日期]
4、hibernate的校验模式
4.1、普通模式(默认)
默认会校验完 所有的属性,然后返回 所有的验证失败信息 。
4.2、快速失败返回模式
只要有一个验证失败,则返回。
4.3、配置
方式一:
failFast:true 快速失败返回模式;false 普通模式
ValidatorFactory validatorFactory
= Validation
.byProvider( HibernateValidator
.class )
.configure()
.failFast( true )
.buildValidatorFactory();
Validator validator
= validatorFactory
.getValidator();
方式二:
hibernate.validator.fail_fast 的取值: true 快速失败返回模式;false 普通模式
ValidatorFactory validatorFactory
= Validation
.byProvider( HibernateValidator
.class )
.configure()
.addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator
= validatorFactory
.getValidator();
5、SpringBoot 时,将 校验模式对象 添加到容器中
@Configuration
public class ValidatorConfiguration {
@Bean
public Validator
validator() {
ValidatorFactory validatorFactory
= Validation
.byProvider(HibernateValidator
.class).configure()
.addProperty("hibernate.validator.fail_fast", "true").buildValidatorFactory();
Validator validator
= validatorFactory
.getValidator();
return validator
;
}
}