前言
通常,当我们需要验证用户输入时,Spring MVC提供了标准的预先定义好的validator
。但是,当我们需要验证更特殊的类型输入时,我们可以创建自定义验证逻辑。在本文中,我们将创建一个自定义validator
来验证一个带有电话号码表单字段。
准备
在pom.xml
文件中添加依赖。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
</dependency>
如果我们使用Spring Boot
,那么我们只能添加Spring - Boot -starter-web
,这也会带来hibernate-validator
依赖项。
自定义validator
因此,让我们创建检查电话号码的自定义validator
。电话号码必须是11位数字。
实现新的注解
让我们实现一个新的注解,用来对手机号进行验证。
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
@Target({ElementType.FIELD}) // 用于描述成员变量
@Constraint(validatedBy = PhoneValidator.class) // 关联PhoneValidator类
public @interface Phone {
String message() default "Invalid phone number";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@Constraint
注解可以用validatedBy
参数来指定验证方法,在这里我们定义了一个类:PhoneValidator
。
message()
是用来显示错误消息的,其余代码是Spring规范定义的样板代码,我们照着写下来即可。
创建 Validator
现在,让我们创建一个validator
类来进行手机号验证
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PhoneValidator implements
ConstraintValidator<Phone, String> {
@Override
public boolean isValid(String phone, ConstraintValidatorContext constraintValidatorContext) {
return phone != null && phone.matches("[0-9]+") && (phone.length()==11) ;
}
}
凡是自定义validator
方法都必须要实现ConstraintValidator<V,F>
接口,且必须重写isValid
方法。我们正是在这个方法中定义了验证逻辑。
关于
ConstraintValidator<A extends Annotation, T>
接口,我们需要注意以下两点:
- 第一个参数:指定我们自定义的注解(在这里我们自定义的的注解是:
@Phone
); - 第二个参数:是需要验证的目标对象的类型 (在这里我们的目标对象类型是:
String
)
自定义注解的使用
在我们的例子中,我们创建了一个简单的表单,它只有一个字段,我们使用我们刚刚定义好的注解来对该字段进行验证。
import lombok.Getter;
import com.sell.validators.Phone;
@Getter
public class PersonForm {
@Phone
private String phone;
}
测试
这是controller
层的代码:
import com.sell.form.PersonForm;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
public class BannerController {
@PostMapping("/test")
public String test(@Validated @RequestBody PersonForm personForm) {
String phone = personForm.getPhone();
System.out.println(phone);
return phone;
}
}
接下来我们就通过以下curl
命令访问这个控制器,来进行表单验证:
curl -d'{"phone":"15288429"}' -H'Content-Type:application/json' http://localhost:8080/v1/test
命令行返回信息如下:
{"code":10001,"message":"Invalid phone number;","request":"POST /v1/test"}