Python 官方文档:入门教程 => 点击学习
目录前言hibernate-validator基本使用 引入依赖 编写需要验证对象 验证对象属性是否符合要求 验证规则 空/非空验证bool时间数学 字符串模板正则 SpringBo
我们这里使用hibernate-validator作为对象参数验证器,所以在正式介绍springBoot参数验证之前,需要先简单了解一下hibernate-validator的使用。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
验证要求 person对象的用户名不能为空,年龄在1-150岁之间。
@Data
public class Person {
@NotBlank(message = "username must not be null")
private String username;
@Min(value = 1, message = "age must be >= 1")
@Max(value = 150, message = "age must be < 150")
private Integer age;
}
public Validator validator() {
ValidatorFactory validatorFactory =
Validation
.byProvider(HibernateValidator.class)
.configure()
// 验证属性时,如果有一个验证不通过就返回,不需要验证所有属性
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
return validatorFactory.getValidator();
}
@Test
public void test() throws Exception {
Person person = new Person();
Set<ConstraintViolation<Person>> validate = validator().validate(person);
validate.forEach(errorParam -> {
System.out.println(errorParam.getMessage());
});
}
username must not be null
validator提供了大量的验证注解供我们使用,主要以下几类:
以下所有验证规则都在元素非空的时候才会进行验证,如果传入的元素为空,验证都会通过。
数字类型可以是BigDecimal、BigInteger、CharSequence 、byte 、 short 、 int 、 long以及它们各自的包装器类型
validator提供了字符串模板正则的注解,这里提供一份常用的正则表达式,大家可以直接作为常量工具类放到项目里使用
public interface ValidatorPattern {
String REGEX_USERNAME = "^[a-zA-Z]\w{5,17}$";
String REGEX_PASSWord = "^(?=.*[a-zA-Z])(?=.*[0-9])[A-Za-z0-9._~!@#$^&*]{6,12}$";
String REGEX_MOBILE = "^[1][34578]\d{9}$";
String REGEX_EMAIL = "^.+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$";
String REGEX_CHINESE = "^[\u4e00-\u9fa5],*$";
String REGEX_ID_CARD = "(^\d{18}$)|(^\d{15}$)";
String REGEX_URL = "Http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
String REGEX_IP_ADDR = "(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)";
String LICENSE_NO = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z][A-Z][A-Z0-9]{4,5}[A-Z0-9挂学警港澳]$";
String NAME = "[\u4e00-\u9fa5\u00b7\sA-Za-z]{1,15}$";
String EMOJI = "[\ud83c\udc00-\ud83c\udfff]|[\ud83D\udc00-\ud83d\udfff]|[\u2600-\u27ff]";
String NUMBER = "^[0-9]*$";
String N_NUMS = "^\d{n}$";
}
这个不再赘述,直接拷贝上文的依赖信息
在配置类中加入hibernate-validator验证器对象
@Bean
@Primary
public Validator validator() {
ValidatorFactory validatorFactory =
Validation
.byProvider(HibernateValidator.class)
.configure()
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
return validatorFactory.getValidator();
}
配置好后,Spring会自动帮助我们进行参数验证,如果参数验证不通过,会抛出BindException异常,我们刚刚手动验证时的Set<ConstraintViolation<Person>>通过该异常获取。
我们这可以通过借助SpringMVC统一异常处理的能力处理这个异常
@Slf4j
@RestControllerAdvice
public class BaseExceptionHandler {
@ResponseStatus(org.springframework.http.httpstatus.PAYMENT_REQUIRED)
@ExceptionHandler(BindException.class)
public R<Void> handler(BindException e) {
String defaultMsg = e.getBindingResult().getAllErrors()
.stream()
.map(ObjectError::getDefaultMessage)
.collect(Collectors.joining(":"));
log.warn(defaultMsg);
return R.of(IRespCode.PARAMETERS_ANOMALIES.getCode(), e.getMessage());
}
}
我们只需要在校验参数的方法传参上标注@Valid或者@Validated都行
@PostMapping("reGISter")
public R<Void> register(@Valid @RequestBody Person person) {
// todo
return R.ok();
}
那么@Valid和@Validated有什么区别呢?
Validated比Valid多了一个属性,这个属性用于分组校验使用
public @interface Valid {
}
public @interface Validated {
Class<?>[] value() default {};
}
就是一个实体类中的属性,在不同的方法传参中,方法的对属性的要求不同。
比如说,Person类中有三个属性,一个是用户名称,一个是邮箱,一个是年龄。
在注册用户接口中,用户名称,邮箱和年龄都不能为空,但是在更改用户的信息接口中,用户的年龄和邮箱都可以为空,但是用户名称不能为空。
这时候,我们就可以按照对属性校验的要求进行分组。
新建一个RegisterGroup分组,该分组只是一个空的接口,仅仅用于标记该校验要求
public interface RegisterGroup {
}
对校验要求进行分组
@Data
public class Person {
@NotBlank(message = "username must not be null")
private String username;
@Min(value = 1, message = "age must be >= 1")
@Max(value = 150, message = "age must be < 150")
@NotNull(message = "age must not be null", groups = RegisterGroup.class)
private Integer age;
@Email(message = "email fORMat error")
@NotBlank(message = "email must not be null",groups = RegisterGroup.class)
private String email;
}
方法调用时,加入分组要求
@PostMapping("register")
public R<Void> register(@Validated(value = RegisterGroup.class) @RequestBody Person person) {
// todo
return R.ok();
}
这种方式其实不推荐使用,我在标题的时候,也已经标记为“过时”,因为,我们完全可以为这两个不同的接口创建两个不同的实体类,而不是使用分组对校验要求进行隔离,因为实际生产环境中,分组可能有非常多个,这会为我们的程序的可读性埋下隐患,后期开发人员难以维护,而且对于自动生成API文档也不友好。大家对于分组只需要了解即可,不建议在项目开发中使用。
到此这篇关于SpringBoot参数校验的文章就介绍到这了,更多相关SpringBoot参数校验内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: SpringBoot参数校验的最佳实战教程
本文链接: https://lsjlt.com/news/133512.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0