javaBean hibernate Validation

    xiaoxiao2024-10-14  70

    文章目录

    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> <!--统一的EL参考实现的Maven依赖关系 --> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <version>3.0.1-b08</version> </dependency> <!--logback --> <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> <!--slf4j不属于logback,但是通常是slf4j配合logback一起来进行使用的 --> <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; } // getter/setter }

    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) { // ValidatorFactory factory2 = Validation.byProvider(HibernateValidator.class).configure().failFast(true) // .buildValidatorFactory(); 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 { }; /** * Defines several {@link FutureStr} annotations on the same element. * * @see FutureStr */ @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) { // this.pastStr = 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); /** * 时间格式(yyyy-MM-dd) */ public final static String DATE_PATTERN = "yyyy-MM-dd"; /** * 时间格式(yyyy-MM-dd HH:mm:ss) */ 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; } /** * 将指定格式的字符串转换为日期对象 * * @param dateStr * 日期对象 * @param format * 日期格式 */ 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; } }
    最新回复(0)