在开发过程中我们会遇到各种数据层面的校验,通常有一下两种方式
1.可以通过[if-else]的方式, 很明显对于一些简单数据验证写大量的if-else判断会影响代码的简洁性。
2 .通过注解形式,对于前端传入的数据,我们可以在接收实体类上加注解比如@NotNull @Pattern等 这样我们的业务逻辑可能会少很多。
引入包:
<!--validation校验依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
在接收实体类上加入注解即可:
@NotNull(message = "id不能为空")
private Long id;
@Max(value = 100)
@Min(value = 0)
private Integer age;
controller层需要加入注解@Validated使之生效
@PostMapping("home")
public String home(@Validated @RequestBody UserInfo userInfo){
return "Home";
}
但是对于一些复杂的校验, 而该工具包又没有给我们提供这样的注解, 我们可以实现约束器接口ConstraintValidator自定义
比如我们可以自己实现一个注解:@Phone 校验手机号是否合法
自定义注解:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = PhoneValidator.class) //使用哪个约束器进行验证
public @interface Phone {
String message() default "手机号不合法";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default { };
}
实现自己的验证器: PhoneValidator, 其中Phone是上面定义的注解
public class PhoneValidator implements ConstraintValidator<Phone, String> {
private final static String regex = "^1[0-9]{10}$"; // 定义手机号格式的正则表达式
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(!StringUtils.hasText(value)){
return false;
}
return Pattern.compile(regex).matcher(value).matches();
}
}
至此就完成了自定义手机号合法性验证的注解, 使用方式和开头描述的一样, 在接收实体类中的属性上加入该注解。
上一张请求示例图: