约定:认为1开头的,紧跟10位数字的字符串是合法手机号
问题:如何判断手机号的合法性?
如果:直接是在后端进行判断:
常规方法:
需要代码判断是否为null,接着验证格式
比如如下代码:
if(StringUtils.isEmpty(loginVal.getMobile())){
return Result.error(CodeMsg.MSG_MOBILE_IS_EMPTY);
}
//ValidatorUtil是自己定义的验证是否是手机号的工具类
if(!ValidatorUtil.isMobile(loginVal.getMobile())){
return Result.error(CodeMsg.MSG_MOBILE_ERROR);
}
缺点:如果是多处使用,或者多个项目使用,不能复用,只能粘贴
高大上,可复用的方法,使用jsr303校验器,封装自己的校验器
org.springframework.boot
spring-boot-starter-validation
可以参考官方的@IsNull
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {}
)
public @interface NotNull {
String message() default "{javax.validation.constraints.NotNull.message}";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
NotNull[] value();
}
}
new 一个注解Annotation
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {IsMobileValidator.class}//指定起校验功能的类,需要实现ConstraintValidator
)
public @interface IsMobile {
boolean required() default true;
String message() default "手机号码格式错误";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
}
IsMobileValidator.java
public class IsMobileValidator implements ConstraintValidator {
private boolean required=false;
@Override
// 初始化方法可以拿到注解
public void initialize(IsMobile isMobile) {
System.out.println("hello isMobile");
required=isMobile.required();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
System.out.println("hello isMobile is valid!!!!");
if(required){
return ValidatorUtil.isMobile(value);
}else{
//允许为空
if(StringUtils.isEmpty(value)){
return true;
}else{
return ValidatorUtil.isMobile(value);
}
}
}
}
import lombok.extern.slf4j.Slf4j;
import java.util.regex.Pattern;
@Slf4j
public class ValidatorUtil {
//暂时认为 1开头,后跟10个数字是手机号
private static final Pattern MOBILE_PATTERN = Pattern.compile("1\\d{10}");
public static boolean isMobile(String mobile){
return MOBILE_PATTERN.matcher(mobile).matches();
}
public static void main(String[] args) {
log.info("123456789;{}",isMobile("123456789"));
log.info("12345678901;{}",isMobile("12345678901"));
}
}
在需要验证的类中属性上 加上@IsMobile注解
在controller层参数前使用: @Valid Object param//表示对参数param启用参数校验
截图:
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
@Data
public class LoginVal {
@NotNull
@IsMobile//使用自定义的参数校验器
private String mobile;
@NotNull
@Length(min=32)
private String password;
}
启动项目,测试controller接口:注意如果手机号是1开头,紧跟10数字认为是合法,这是定义在自定义的格式校验工具类ValidatorUtil中
正常输入手机号:
不合法手机号:证明已经起作用了!!
使用jsr参数校验,可以方便的解决多个地方使用同一规则校验参数的问题,但是这里还有些需要优化的地方,那就是返回的提示信息很不友好,不可能让用户去f2查看控制台吧!
下一篇介绍springboot定义全局异常拦截器