Spring Boot集成Hibernate Validator
废话不多说,直接开始集成环境。
一、环境集成
在项目中hibernate-Validator包在spring-boot-starter-web
包里面有,不需要重复引用 。(整个Demo都是用PostMan软件进行数据传输。
)
二、Demo实例
此Mode中添加了些简单、常用的Validator注解
1 import com.shida.api.baseData.validatorUtils.IsMobile; 2 import org.hibernate.validator.constraints.Length; 3 import javax.validation.Valid; 4 import javax.validation.constraints.NotNull; 5 import java.io.Serializable; 6 7 public class AccountVO implements Serializable { 8 9 /** 10 * 手机号 11 */ 12 @IsMobile 13 private String account; 14 15 /** 16 * 密码 17 */ 18 @NotNull 19 @Length(min = 1 , max = 6 , message = "密码不能为空且长度需要在1和6之间") 20 private String password; 21 22 /** 23 * 账户状态 24 */ 25 @NotNull(message = "账号状态不能为空") 26 private Integer status; 27 28 /** 29 * 账户扩展信息 30 */ 31 @Valid 32 private UserInfoVO userInfoVO; 33 34 public String getAccount() {return account;} 35 36 public void setAccount(String account) {this.account = account;} 37 38 public String getPassword() {return password;} 39 40 public void setPassword(String password) {this.password = password;} 41 42 public Integer getStatus() {return status;} 43 44 public void setStatus(Integer status) { this.status = status;} 45 46 public UserInfoVO getUserInfoVO() {return userInfoVO;} 47 48 public void setUserInfoVO(UserInfoVO userInfoVO) {this.userInfoVO = userInfoVO;} 49 }
接下来Post接口验证,Controller中调用DemoVO验证集合校验情况:
1 package com.shida.account.center.controller; 2 3 4 import com.base.data.common.message.MessageVo; 5 import com.base.data.common.message.StatusCode; 6 import com.shida.account.center.service.IAccountService; 7 import com.shida.api.baseData.model.AccountVO; 8 import org.springframework.validation.annotation.Validated; 9 import org.springframework.web.bind.annotation.*; 10 import org.springframework.web.bind.annotation.PostMapping; 11 import org.springframework.web.bind.annotation.RequestMapping; 12 import org.springframework.web.bind.annotation.RestController; 13 14 import javax.annotation.Resource; 15 import javax.validation.Valid; 16 17 @RestController 18 @Validated 19 @RequestMapping("/data/account") 20 public class AccountController { 21 22 @Resource 23 private IAccountService accountService; 24 25 /** 26 * 添加账户 27 * @param accountVO 28 * @return 29 */ 30 @PostMapping(value = "/add") 31 public MessageVo addAccount(@Valid @RequestBody AccountVO accountVO){ 32 MessageVo message = new MessageVo(); 33 accountService.addAccount(accountVO); 34 message.setCode(StatusCode.success); 35 message.setMsg("账户添加成功"); 36 message.setResult(accountVO); 37 return message; 38 } 39 }
PostMan请求入参:
PostMan返回结果:(MessageVo是我自己写的一个返回Mode,用于承载返回结果。)
{ "code": "204", "msg": "前后端校验发生异常+[accountVO.account:手机号码错误][accountVO.password:密码不能为空][accountVO.status:账号状态不能为空]", "result": null }
注:如果实体类想参与校验则需要在实体类前加@Valid注解。不加则不参与校验。
三、对象级联校验填坑。
1、对象级联校验方式。
对象级联校验Mode为对象内部包含另一个对象最为属性。内部对象也需要加入@Valid注解。则开启内部对象校验。(如果用PostMan作为自测接口方式,需要另加@RequestBody注解,RequestBody会自动将参数分配到各个Type中。否则会报错。)
集合类的入参同样也需要用@RequestBody注解。
controller实例:
public MessageVo addAccount(@Valid @RequestBody AccountVO accountVO){ MessageVo message = new MessageVo(); return message; }
Mode实例:
1 public class AccountVO implements Serializable { 2 3 @IsMobile 4 private String account; 5 6 @Valid 7 private UserInfoVO userInfoVO; 8 9 }
UserInfoVO实例:
1 public class UserInfoVO implements Serializable { 2 3 @NotNull 4 private Integer sex; 5 6 }
PostMan校验结果:
四、自定义校验器
一般情况,自定义验证可以解决很多问题。但也有无法满足情况的时候,此时,我们可以实现validator的接口,自定义自己需要的验证器。如下所示,实现了一个自定义的大小写验证器:
1 public enum CaseMode { 2 UPPER, 3 LOWER; 4 } 5 6 7 @Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE }) 8 @Retention(RetentionPolicy.RUNTIME) 9 @Constraint(validatedBy = CheckCaseValidator.class) 10 @Documented 11 public @interface CheckCase { 12 String message() default ""; 13 14 Class<?>[] groups() default {}; 15 16 Class<? extends Payload>[] payload() default {}; 17 18 CaseMode value(); 19 } 20 21 22 public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> { 23 private CaseMode caseMode; 24 public void initialize(CheckCase checkCase) { 25 this.caseMode = checkCase.value(); 26 } 27 28 public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { 29 if (s == null) { 30 return true; 31 } 32 33 if (caseMode == CaseMode.UPPER) { 34 return s.equals(s.toUpperCase()); 35 } else { 36 return s.equals(s.toLowerCase()); 37 } 38 } 39 }
要验证的Model:
1 public class Demo{ 2 @CheckCase(value = CaseMode.LOWER,message = "userName必须是小写") 3 private String userName; 4 5 public String getUserName() { 6 return userName; 7 } 8 9 public void setUserName(String userName) { 10 this.userName = userName; 11 } 12 }
validator配置:
1 @Bean 2 public Validator validator(){ 3 ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) 4 .configure() 5 .addProperty( "hibernate.validator.fail_fast", "true" ) 6 .buildValidatorFactory(); 7 Validator validator = validatorFactory.getValidator(); 8 9 return validator; 10 }
验证测试:
1 @RequestMapping("/demo4") 2 public void demo4(){ 3 Demo demo = new Demo(); 4 demo.setUserName("userName"); 5 Set<ConstraintViolation<Demo>> validate = validator.validate(demo); 6 for (ConstraintViolation<Demo> dem : validate) { 7 System.out.println(dem.getMessage()); 8 } 9 }
输出结果:
userName必须是小写
五、常见注解。
1 Bean Validation 中内置的 constraint 2 @Null 被注释的元素必须为 null 3 @NotNull 被注释的元素必须不为 null 4 @AssertTrue 被注释的元素必须为 true 5 @AssertFalse 被注释的元素必须为 false 6 @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 7 @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 8 @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 9 @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 10 @Size(max=, min=) 被注释的元素的大小必须在指定的范围内 11 @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内 12 @Past 被注释的元素必须是一个过去的日期 13 @Future 被注释的元素必须是一个将来的日期 14 @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式 15 Hibernate Validator 附加的 constraint 16 @NotBlank(message =) 验证字符串非null,且长度必须大于0 17 @Email 被注释的元素必须是电子邮箱地址 18 @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内 19 @NotEmpty 被注释的字符串的必须非空 20 @Range(min=,max=,message=) 被注释的元素必须在合适的范围内
六、参考资料
https://www.cnblogs.com/mr-yang-localhost/p/7812038.html#_label5