空值校验类:@Null,@NotNull,@NotEmpty,@NotBlank等
范围校验类:@Min,@Size,@Digits,@Future,@Negative等
其他校验类:@Email,@URL,@AssertTrue,@Pattern等
1 <!-- Validation 相关依赖 --> 2 <dependency> 3 <groupId>javax.validation</groupId> 4 <artifactId>validation-api</artifactId> 5 <version>2.0.1.Final</version> 6 </dependency> 7 <dependency> 8 <groupId>org.hibernate</groupId> 9 <artifactId>hibernate-validator</artifactId> 10 <version>6.0.16.Final</version> 11 </dependency> 12 <dependency> 13 <groupId>javax.el</groupId> 14 <artifactId>javax.el-api</artifactId> 15 <version>3.0.0</version> 16 </dependency> 17 <dependency> 18 <groupId>org.glassfish.web</groupId> 19 <artifactId>javax.el</artifactId> 20 <version>2.2.6</version> 21 </dependency>
1 import org.hibernate.validator.constraints.Length; 2 3 import javax.validation.GroupSequence; 4 import javax.validation.Valid; 5 import javax.validation.constraints.*; 6 import javax.validation.groups.Default; 7 import java.util.Date; 8 import java.util.List; 9 10 /** 11 * 待验证对象实体类 12 * 用户信息类 13 */ 14 public class UserInfo { 15 16 17 // 登录场景 18 public interface LoginGroup {} 19 20 // 注册场景 21 public interface RegisterGroup {} 22 23 // 组排序场景 24 @GroupSequence({ 25 LoginGroup.class, 26 RegisterGroup.class, 27 Default.class 28 }) 29 public interface Group {} 30 31 /** 32 * 用户ID 33 */ 34 @NotNull(message = "用户ID不能为空", 35 groups = LoginGroup.class) 36 private String userId; 37 38 /** 39 * 用户名 40 * NotEmpty 不会自动去掉前后空格 41 */ 42 @NotEmpty(message = "用户名称不能为空") 43 private String userName; 44 45 /** 46 * 用户密码 47 * NotBlank 自动去掉字符串前后空格后验证是否为空 48 */ 49 @NotBlank(message = "用户密码不能为空") 50 @Length(min = 6, max = 20, 51 message = "密码长度不能少于6位,多于20位") 52 private String passWord; 53 54 /** 55 * 邮箱 56 */ 57 @NotNull(message = "邮箱不能为空", 58 groups = RegisterGroup.class) 59 @Email(message = "邮箱必须为有效邮箱") 60 private String email; 61 62 /** 63 * 手机号 64 */ 65 @Phone(message = "手机号不是158后头随便") 66 private String phone; 67 68 /** 69 * 年龄 70 */ 71 @Min(value = 18, message = "年龄不能小于18岁") 72 @Max(value = 60, message = "年龄不能大于60岁") 73 private Integer age; 74 75 /** 76 * 生日 77 */ 78 @Past(message = "生日不能为未来或当前时间点") 79 private Date birthday; 80 81 /** 82 * 好友列表 83 */ 84 @Size(min = 1, message = "不能少于1个好友") 85 private List<@Valid UserInfo> friends; 86 87 public void setUserId(String userId) { 88 this.userId = userId; 89 } 90 91 public void setUserName(String userName) { 92 this.userName = userName; 93 } 94 95 public void setPassWord(String passWord) { 96 this.passWord = passWord; 97 } 98 99 public void setEmail(String email) { 100 this.email = email; 101 } 102 103 public void setPhone(String phone) { 104 this.phone = phone; 105 } 106 107 public void setAge(Integer age) { 108 this.age = age; 109 } 110 111 public void setBirthday(Date birthday) { 112 this.birthday = birthday; 113 } 114 115 public void setFriends(List<UserInfo> friends) { 116 this.friends = friends; 117 } 118 119 public String getUserId() { 120 return this.userId; 121 } 122 123 public String getUserName() { 124 return this.userName; 125 } 126 127 public String getPassWord() { 128 return this.passWord; 129 } 130 131 public String getEmail() { 132 return this.email; 133 } 134 135 public String getPhone() { 136 return this.phone; 137 } 138 139 public Integer getAge() { 140 return this.age; 141 } 142 143 public Date getBirthday() { 144 return this.birthday; 145 } 146 147 public List<UserInfo> getFriends() { 148 return this.friends; 149 } 150 }
1 import javax.validation.Valid; 2 3 /** 4 * 用户信息服务类 5 */ 6 public class UserInfoService { 7 8 /** 9 * UserInfo 作为输入参数 10 * @param userInfo 11 */ 12 public void setUserInfo(@Valid UserInfo userInfo) {} 13 14 /** 15 * UserInfo 作为输出参数 16 * @return 17 */ 18 public @Valid UserInfo getUserInfo() { 19 return new UserInfo(); 20 } 21 22 /** 23 * 默认构造函数 24 */ 25 public UserInfoService() {} 26 27 /** 28 * 接收UserInfo作为参数的构造函数 29 * @param userInfo 30 */ 31 public UserInfoService(@Valid UserInfo userInfo) {} 32 33 }
1 import javax.validation.Constraint; 2 import javax.validation.Payload; 3 import java.lang.annotation.*; 4 5 /** 6 * 自定义手机号约束注解 7 */ 8 @Documented 9 // 注解的作用目标 10 @Target({ElementType.FIELD}) 11 // 注解的保留策略 12 @Retention(RetentionPolicy.RUNTIME) 13 // 不同之处:于约束注解关联的验证器 14 @Constraint(validatedBy = PhoneValidator.class) 15 public @interface Phone { 16 17 // 约束注解验证时的输出信息 18 String message() default "手机号校验错误"; 19 20 // 约束注解在验证时所属的组别 21 Class<?>[] groups() default {}; 22 23 // 约束注解的有效负载 24 Class<? extends Payload>[] payload() default {}; 25 }
1 import javax.validation.ConstraintValidator; 2 import javax.validation.ConstraintValidatorContext; 3 import java.util.Optional; 4 import java.util.regex.Matcher; 5 import java.util.regex.Pattern; 6 7 /** 8 * 自定义手机号约束注解关联验证器 9 */ 10 public class PhoneValidator 11 implements ConstraintValidator<Phone, String> { 12 13 /** 14 * 自定义校验逻辑方法 15 * @param value 16 * @param context 17 * @return 18 */ 19 @Override 20 public boolean isValid(String value, 21 ConstraintValidatorContext context) { 22 23 // 手机号验证规则:158后头随便 24 String check = "158\\d{8}"; 25 Pattern regex = Pattern.compile(check); 26 27 // 空值处理 28 String phone = Optional.ofNullable(value).orElse(""); 29 Matcher matcher = regex.matcher(phone); 30 31 return matcher.matches(); 32 } 33 }
1 import org.junit.After; 2 import org.junit.Before; 3 import org.junit.Test; 4 5 import javax.validation.ConstraintViolation; 6 import javax.validation.Validation; 7 import javax.validation.Validator; 8 import javax.validation.executable.ExecutableValidator; 9 import java.lang.reflect.Constructor; 10 import java.lang.reflect.InvocationTargetException; 11 import java.lang.reflect.Method; 12 import java.util.ArrayList; 13 import java.util.Calendar; 14 import java.util.Optional; 15 import java.util.Set; 16 import java.util.stream.Stream; 17 18 /** 19 * 验证测试类 20 */ 21 public class ValidationTest { 22 23 // 验证器对象 24 private Validator validator; 25 // 待验证对象 26 private UserInfo userInfo; 27 // 验证结果集合 28 private Set<ConstraintViolation<UserInfo>> set; 29 // 验证结果集合 30 private Set<ConstraintViolation<UserInfoService>> otherSet; 31 32 /** 33 * 初始化操作 34 */ 35 @Before 36 public void init() { 37 //初始化验证器 38 validator = Validation.buildDefaultValidatorFactory().getValidator(); 39 40 //初始化验证器对象 41 userInfo = new UserInfo(); 42 userInfo.setUserId("000001"); 43 userInfo.setUserName("ming"); 44 userInfo.setPassWord("123456"); 45 // userInfo.setEmail("zhangxiaoxi@sina.cn"); 46 userInfo.setAge(30); 47 Calendar calendar = Calendar.getInstance(); 48 calendar.set(2012, 1, 1); 49 userInfo.setBirthday(calendar.getTime()); 50 51 userInfo.setPhone("15800000000"); 52 53 UserInfo friend = new UserInfo(); 54 // friend.setUserId("wangxiaoxi"); 55 friend.setUserName("王小喜"); 56 friend.setPassWord("wangxiaoxi"); 57 // friend.setEmail("wangxiaoxi@sina.cn"); 58 friend.setPhone("15811111111"); 59 60 userInfo.setFriends(new ArrayList(){{add(friend);}}); 61 } 62 63 /** 64 * 结果打印 65 */ 66 @After 67 public void print() { 68 69 Optional.ofNullable(set) 70 .map(Set::stream) 71 .orElseGet(Stream::empty) 72 .forEach(item -> { 73 //使用验证器对象进行验证 74 System.out.println(item.getMessage()); 75 }); 76 77 Optional.ofNullable(otherSet) 78 .map(Set::stream) 79 .orElseGet(Stream::empty) 80 .forEach(item -> { 81 //使用验证器对象进行验证 82 System.out.println(item.getMessage()); 83 }); 84 } 85 86 @Test 87 public void nullValidation() { 88 set = validator.validate(userInfo); 89 } 90 91 /** 92 * 级联验证测试方法 93 */ 94 @Test 95 public void graphValidation() { 96 set = validator.validate(userInfo); 97 } 98 99 /** 100 * 分组验证测试方法 101 */ 102 @Test 103 public void groupValidation() { 104 set = validator.validate(userInfo, 105 UserInfo.RegisterGroup.class, 106 UserInfo.LoginGroup.class); 107 } 108 109 /** 110 * 组序列 111 */ 112 @Test 113 public void groupSequenceValidation() { 114 set = validator.validate(userInfo, 115 UserInfo.Group.class); 116 } 117 118 /** 119 * 对方法输入参数进行约束注解校验 120 */ 121 @Test 122 public void paramValidation() throws NoSuchMethodException { 123 // 获取校验执行器 124 ExecutableValidator executableValidator = 125 validator.forExecutables(); 126 127 // 待验证对象 128 UserInfoService service = new UserInfoService(); 129 // 待验证方法 130 Method method = service.getClass() 131 .getMethod("setUserInfo", UserInfo.class); 132 // 方法输入参数 133 Object[] paramObjects = new Object[]{new UserInfo()}; 134 135 // 对方法的输入参数进行校验 136 otherSet = executableValidator.validateParameters( 137 service, 138 method, 139 paramObjects); 140 } 141 142 /** 143 * 对方法返回值进行约束校验 144 */ 145 @Test 146 public void returnValueValidation() 147 throws NoSuchMethodException, 148 InvocationTargetException, IllegalAccessException { 149 150 // 获取校验执行器 151 ExecutableValidator executableValidator = 152 validator.forExecutables(); 153 154 // 构造要验证的方法对象 155 UserInfoService service = new UserInfoService(); 156 Method method = service.getClass() 157 .getMethod("getUserInfo"); 158 159 // 调用方法得到返回值 160 Object returnValue = method.invoke(service); 161 162 // 校验方法返回值是否符合约束 163 otherSet = executableValidator.validateReturnValue( 164 service, 165 method, 166 returnValue); 167 } 168 169 /** 170 * 对构造函数输入参数进行校验 171 */ 172 @Test 173 public void constructorValidation() 174 throws NoSuchMethodException { 175 176 // 获取验证执行器 177 ExecutableValidator executableValidator = 178 validator.forExecutables(); 179 180 // 获取构造函数 181 Constructor constructor = 182 UserInfoService.class 183 .getConstructor(UserInfo.class); 184 Object[] paramObjects = new Object[]{new UserInfo()}; 185 186 // 校验构造函数 187 otherSet = executableValidator 188 .validateConstructorParameters( 189 constructor, paramObjects); 190 191 } 192 }
原文:https://www.cnblogs.com/mingmingn/p/13198692.html