要实现自定义注解校验前端传参,需要使用到Java中的ConstraintValidator
类。以下是实现的步骤:
- 创建自定义注解
首先需要创建一个自定义注解,并定义需要校验的参数和校验条件。下面的示例定义了一个名为CheckPassword
的注解,用来校验密码是否符合规定的长度和包含数字、字母和特殊字符:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPassword {
String message() default "Invalid password format";
int minLength() default 6;
int maxLength() default 20;
boolean needNumber() default true;
boolean needLowerCase() default true;
boolean needUpperCase() default true;
boolean needSpecialChar() default true;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
- 创建校验器
通过实现ConstraintValidator
接口,我们可以自定义校验逻辑,并将其与注解绑定起来。以下是实现PasswordValidator
校验器的示例代码:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class PasswordValidator implements ConstraintValidator<CheckPassword, String> {
private int minLength;
private int maxLength;
private boolean needNumber;
private boolean needLowerCase;
private boolean needUpperCase;
private boolean needSpecialChar;
@Override
public void initialize(CheckPassword constraintAnnotation) {
this.minLength = constraintAnnotation.minLength();
this.maxLength = constraintAnnotation.maxLength();
this.needNumber = constraintAnnotation.needNumber();
this.needLowerCase = constraintAnnotation.needLowerCase();
this.needUpperCase = constraintAnnotation.needUpperCase();
this.needSpecialChar = constraintAnnotation.needSpecialChar();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.isEmpty()) {
return true; // empty value is valid
}
if (value.length() < minLength || value.length() > maxLength) {
return false;
}
if (needNumber && !Pattern.compile("[0-9]").matcher(value).find()) {
return false;
}
if (needLowerCase && !Pattern.compile("[a-z]").matcher(value).find()) {
return false;
}
if (needUpperCase && !Pattern.compile("[A-Z]").matcher(value).find()) {
return false;
}
if (needSpecialChar && !Pattern.compile("[!\"#$%&'()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~]").matcher(value).find()) {
return false;
}
return true;
}
}
在initialize()
方法中,我们可以获得注解的参数,以便根据不同的参数设置不同的校验规则。isValid()
方法是校验逻辑的核心,返回true
表示参数符合要求,而返回false
则表示参数不符合要求。
- 在Controller中使用自定义注解
当我们需要校验某个Controller方法中的参数时,只需在参数上使用自定义的注解即可。例如,以下示例中的registerUser()
方法就使用了CheckPassword
注解对密码进行了校验:
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
@Validated // enable validation globally
public class UserController {
@PostMapping("/register")
public ResponseEntity<String> registerUser(
@RequestParam String username,
@CheckPassword @RequestParam String password,
@RequestParam String email) {
// do something...
}
}
在@CheckPassword
注解之前加上@Validated
注解,可以启用全局参数校验。这样,当前端使用HTTP POST方法调用/api/register
接口时,就会对password
参数进行校验。如果校验失败,将返回HTTP状态码为400的错误响应,其中包含一个错误消息,消息内容为自定义注解中message
属性指定的内容。
- 示例说明
示例1:校验数字验证码
对于一个需要使用短信验证码的场景,当我们想要验证用户输入的短信验证码是否正确时,就可以使用自定义注解来实现。定义一个名为CheckSmsCode
的注解,用于验证短信验证码是否正确:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = SmsCodeValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckSmsCode {
String message() default "Invalid sms code";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
定义SmsCodeValidator
校验器,用于校验短信验证码是否正确:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class SmsCodeValidator implements ConstraintValidator<CheckSmsCode, String> {
@Override
public void initialize(CheckSmsCode constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// validate sms code here
return false; // TODO: implement this
}
}
在Controller中使用自定义注解:
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
@Validated // enable validation globally
public class SmsController {
@PostMapping("/verify")
public ResponseEntity<String> verifySmsCode(
@RequestParam String phone,
@CheckSmsCode @RequestParam String smsCode) {
// do something...
}
}
示例2:校验密码强度
对于一个需要使用复杂密码的场景,当我们想要验证用户输入的密码是否符合要求时,也可以使用自定义注解来实现。定义一个名为CheckPassword
的注解,用于验证密码是否符合要求:
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPassword {
String message() default "Invalid password format";
int minLength() default 6;
int maxLength() default 20;
boolean needNumber() default true;
boolean needLowerCase() default true;
boolean needUpperCase() default true;
boolean needSpecialChar() default true;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
定义PasswordValidator
校验器,用于校验密码强度是否符合要求:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class PasswordValidator implements ConstraintValidator<CheckPassword, String> {
private int minLength;
private int maxLength;
private boolean needNumber;
private boolean needLowerCase;
private boolean needUpperCase;
private boolean needSpecialChar;
@Override
public void initialize(CheckPassword constraintAnnotation) {
this.minLength = constraintAnnotation.minLength();
this.maxLength = constraintAnnotation.maxLength();
this.needNumber = constraintAnnotation.needNumber();
this.needLowerCase = constraintAnnotation.needLowerCase();
this.needUpperCase = constraintAnnotation.needUpperCase();
this.needSpecialChar = constraintAnnotation.needSpecialChar();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.isEmpty()) {
return true; // empty value is valid
}
if (value.length() < minLength || value.length() > maxLength) {
return false;
}
if (needNumber && !Pattern.compile("[0-9]").matcher(value).find()) {
return false;
}
if (needLowerCase && !Pattern.compile("[a-z]").matcher(value).find()) {
return false;
}
if (needUpperCase && !Pattern.compile("[A-Z]").matcher(value).find()) {
return false;
}
if (needSpecialChar && !Pattern.compile("[!\"#$%&'()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~]").matcher(value).find()) {
return false;
}
return true;
}
}
在Controller中使用自定义注解:
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
@Validated // enable validation globally
public class UserController {
@PostMapping("/register")
public ResponseEntity<String> registerUser(
@RequestParam String username,
@CheckPassword @RequestParam String password,
@RequestParam String email) {
// do something...
}
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ConstraintValidator类如何实现自定义注解校验前端传参 - Python技术站