Maven依赖
1 <dependency>2 <groupId>org.hibernate.validator</groupId>3 <artifactId>hibernate-validator</artifactId>4 <version>6.2.3.Final</version>5</dependency>
分组校验
当对同一个字段在不同情况下(不同方法)需要有不同的校验规则时,可以使用分组校验。
比如新增商品时禁止携带商品 id,需要使用 @Null
注解, 但是修改商品时必须携带商品 id,需要使用 @NotNull注解。
校验注解中一般都有 groups
属性:
1@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })2@Retention(RUNTIME)3@Repeatable(List.class)4@Documented5@Constraint(validatedBy = { })6public @interface Null {7
8 String message() default "{javax.validation.constraints.Null.message}";9
10 Class<?>[] groups() default { };11
12 Class<? extends Payload>[] payload() default { };13
14 @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })15 @Retention(RUNTIME)6 collapsed lines
16 @Documented17 @interface List {18
19 Null[] value();20 }21}
可以设置 id 的校验注解如下:
1@Null(message = "添加不能指定id", groups = {SaveGroup.class})2@NotNull(message = "修改需要指定id", groups = {UpdateGroup.class})3@TableId4private Long id;
其中 SaveGroup
和 UpdateGroup
只是两个作为标识的接口
Controller层:
1@RestController2public class GoodsController{3 @RequestMapping("/save")4 public Result save(@Validated({SaveGroup.class} @RequestBody Goods good)){5 ...6 }7 @RequestMapping("/update")8 public Result update(@Validated({UpdateGroup.class} @RequestBody Goods good)){9 ...10 }11}
自定义校验器
在项目中经常会遇到需要对前端传过来的参数进行校验,但是在使用正则表达式校验数值类型的字段时是不会生效的,比如下面这个案例就会报错:
1@Pattern(regexp = "/^[0-1]$/", message="显示状态必须为0或1")2private Integer status;
这个时候可以使用自定义校验注解:
1@EnumValidation(values={0,1}, group={SaveGroup.class, UpdateGroup.class})2private Integer status;
注解:
1import javax.validation.Constraint;2import javax.validation.Payload;3import java.lang.annotation.Documented;4import java.lang.annotation.Retention;5import java.lang.annotation.Target;6
7import static java.lang.annotation.ElementType.*;8import static java.lang.annotation.RetentionPolicy.RUNTIME;9
10/**11 * @author zql12 * @version 1.013 * 自定义校验注解14 * 1. @Constraint(validatedBy = { }) 可以指定该注解和校验器关联15 * 2. message() default "{}" 指定返回的错误信息--ValidationMessages.properties(Unicode格式)14 collapsed lines
16 */17@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})18@Retention(RUNTIME)19@Documented20@Constraint(validatedBy = {EnumConstraintValidator.class})21public @interface EnumValidation {22 String message() default "{com.njupt.valid.EnumValidation.message}";23
24 Class<?>[] groups() default {};25
26 Class<? extends Payload>[] payload() default {};27
28 int[] values() default {};29}
需要注意的是注解的message属性值,这里填入的是 package name.EnumValidation.message,需要在Resources
目录下建立ValidationMessages.properties
文件,且需要转成Unicode编码格式:
1com.njupt.valid.EnumValidation.message=\u663E\u793A\u72B6\u6001\u7684\u503C\u5FC5\u987B\u4E3A\u0030\u6216\u8005\u0031
校验器:
1import javax.validation.ConstraintValidator;2import javax.validation.ConstraintValidatorContext;3import java.util.HashSet;4import java.util.Set;5
6/**7 * @author 左齐亮8 * @version 1.09 * 自定义校验器10 */11public class EnumConstraintValidator implements ConstraintValidator<EnumValidation, Integer> {12
13 private Set<Integer> set = new HashSet<>();14
15 @Override14 collapsed lines
16 public void initialize(EnumValidation constraintAnnotation) {17 // 获取注解传入的values18 int[] values = constraintAnnotation.values();19 for (int value : values) {20 set.add(value);21 }22 }23
24 @Override25 public boolean isValid(Integer value, ConstraintValidatorContext context) {26 // 参数value是请求携带的参数值27 return set.contains(value);28 }29}