Spring Boot集成Hibernate Validator

时间:2023-03-09 19:30:44
Spring Boot集成Hibernate Validator

废话不多说,直接开始集成环境。

一、环境集成

  在项目中hibernate-Validator包在spring-boot-starter-web包里面有,不需要重复引用 。(整个Demo都是用PostMan软件进行数据传输。

二、Demo实例

  此Mode中添加了些简单、常用的Validator注解

 import com.shida.api.baseData.validatorUtils.IsMobile;
import org.hibernate.validator.constraints.Length;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable; public class AccountVO implements Serializable { /**
* 手机号
*/
@IsMobile
private String account; /**
* 密码
*/
@NotNull
@Length(min = 1 , max = 6 , message = "密码不能为空且长度需要在1和6之间")
private String password; /**
* 账户状态
*/
@NotNull(message = "账号状态不能为空")
private Integer status; /**
* 账户扩展信息
*/
@Valid
private UserInfoVO userInfoVO; public String getAccount() {return account;} public void setAccount(String account) {this.account = account;} public String getPassword() {return password;} public void setPassword(String password) {this.password = password;} public Integer getStatus() {return status;} public void setStatus(Integer status) { this.status = status;} public UserInfoVO getUserInfoVO() {return userInfoVO;} public void setUserInfoVO(UserInfoVO userInfoVO) {this.userInfoVO = userInfoVO;}
}

接下来Post接口验证,Controller中调用DemoVO验证集合校验情况:

 package com.shida.account.center.controller;

 import com.base.data.common.message.MessageVo;
import com.base.data.common.message.StatusCode;
import com.shida.account.center.service.IAccountService;
import com.shida.api.baseData.model.AccountVO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource;
import javax.validation.Valid; @RestController
@Validated
@RequestMapping("/data/account")
public class AccountController { @Resource
private IAccountService accountService; /**
* 添加账户
* @param accountVO
* @return
*/
@PostMapping(value = "/add")
public MessageVo addAccount(@Valid @RequestBody AccountVO accountVO){
MessageVo message = new MessageVo();
accountService.addAccount(accountVO);
message.setCode(StatusCode.success);
message.setMsg("账户添加成功");
message.setResult(accountVO);
return message;
}
}

PostMan请求入参:

Spring Boot集成Hibernate Validator

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实例:

 public class AccountVO implements Serializable {

     @IsMobile
private String account; @Valid
private UserInfoVO userInfoVO; }

  UserInfoVO实例:

 public class UserInfoVO implements Serializable {

     @NotNull
private Integer sex; }

  PostMan校验结果:

Spring Boot集成Hibernate Validator

四、自定义校验器

  一般情况,自定义验证可以解决很多问题。但也有无法满足情况的时候,此时,我们可以实现validator的接口,自定义自己需要的验证器。如下所示,实现了一个自定义的大小写验证器:

 public enum CaseMode {
UPPER,
LOWER;
} @Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CheckCaseValidator.class)
@Documented
public @interface CheckCase {
String message() default ""; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; CaseMode value();
} public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> {
private CaseMode caseMode;
public void initialize(CheckCase checkCase) {
this.caseMode = checkCase.value();
} public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (s == null) {
return true;
} if (caseMode == CaseMode.UPPER) {
return s.equals(s.toUpperCase());
} else {
return s.equals(s.toLowerCase());
}
}
}

要验证的Model:

     public class Demo{
@CheckCase(value = CaseMode.LOWER,message = "userName必须是小写")
private String userName; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
}
}

validator配置:

     @Bean
public Validator validator(){
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator(); return validator;
}

验证测试:

     @RequestMapping("/demo4")
public void demo4(){
Demo demo = new Demo();
demo.setUserName("userName");
Set<ConstraintViolation<Demo>> validate = validator.validate(demo);
for (ConstraintViolation<Demo> dem : validate) {
System.out.println(dem.getMessage());
}
}

输出结果:

   userName必须是小写

五、常见注解。

  

 Bean Validation 中内置的 constraint
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

六、参考资料  

https://www.cnblogs.com/mr-yang-localhost/p/7812038.html#_label5