废话不多说,直接开始集成环境。
一、环境集成
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、对象级联校验方式。
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=) 被注释的元素必须在合适的范围内