[英]How to join several validation annotations
I have following annotation to validate password:我有以下注释来验证密码:
@Target({FIELD})
@Retention(RUNTIME)
@Documented
@NotNull
@Length(min = 8, max = 32)
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$")
public @interface Password {
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
But spring validation does not recognize this rules.但是 spring 验证不承认这个规则。 I used this annotation as:我将此注释用作:
@Password
private String password;
How can I get it without defining ConstraintValidator
instance?如何在不定义ConstraintValidator
实例的情况下获得它?
If you want to use ConstraintValidator
, you can do it like this:如果你想使用ConstraintValidator
,你可以这样做:
create Password annotation :创建密码注释:
@Documented
@Constraint(validatedBy = PasswordConstraintValidator.class)
@Target({ FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface Password {
String message() default "{propertyPath} is not a valid password";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
then create the PasswordConstraintValidator class :然后创建 PasswordConstraintValidator 类:
public class PasswordConstraintValidator implements ConstraintValidator<Password, String> {
private final String PASSWORD_PATTERN =
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#&()–[{}]:;',?/*~$^+=<>]).{8,20}$";
private final Pattern pattern = Pattern.compile(PASSWORD_PATTERN);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(Objects.isNull(value)) {
return false;
}
if((value.length() < 8) || (value.length() > 32)) {
return false;
}
if(!pattern.matcher(password).matches()){
return false;
}
}
Then apply it to one of your fields, note that you can also put a custom message:然后将其应用于您的一个字段,请注意,您还可以放置自定义消息:
@Password(message = "....")
private String password;
@Password
private String passwd;
You can also refactor the if statements each in an appropriate method (to have a clean code): something that will look like this :您还可以在适当的方法中重构每个 if 语句(以获得干净的代码):看起来像这样:
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return (notNull(value) && isValidPasswordLength(value) && isValidPasswordValue(value));
}
Update更新
since you don't want to use the ConstraintValidator
, your implementation looks fine, you just need to add @Valid
on your model so that cascading validation can be performed and include spring-boot-starter-validation
to make sure that validation api is included and add @Constraint(validatedBy = {})
on your custom annotation.由于您不想使用ConstraintValidator
,您的实现看起来不错,您只需要在模型上添加@Valid
以便可以执行级联验证并包含spring-boot-starter-validation
以确保包含验证 api并在您的自定义注释上添加@Constraint(validatedBy = {})
。 Here is a groovy example here (you can run it with spring CLI ) :这是这里的一个groovy示例(您可以使用spring CLI运行它):
@Grab('spring-boot-starter-validation')
@Grab('lombok')
import lombok.*
@Grab('javax.validation:validation-api:2.0.1.Final')
import javax.validation.constraints.NotNull
import javax.validation.constraints.Size
import javax.validation.Valid
import javax.validation.Constraint
import javax.validation.Payload
import java.lang.annotation.Documented
import java.lang.annotation.Target
import java.lang.annotation.Retention
import static java.lang.annotation.ElementType.FIELD
import static java.lang.annotation.RetentionPolicy.RUNTIME
@RestController
class TestCompositeAnnotation {
@PostMapping(value = "/register", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public String register(@Valid @RequestBody User user) {
return "password " + user.password + " is valid";
}
}
class User {
public String username;
@Password
public String password;
}
@Target(value = FIELD)
@Retention(RUNTIME)
@Documented
@NotNull
@Constraint(validatedBy = []) // [] is for groovy make sure to replace is with {}
@Size(min = 8, max = 32)
@interface Password {
String message() default "invalid password";
Class<?>[] groups() default []; // [] is for groovy make sure to replace is with {}
Class<? extends Payload>[] payload() default []; // [] is for groovy make sure to replace is with {}
}
So when you curl :所以当你卷曲时:
curl -X POST http://localhost:8080/register -d '{"username": "rsone", "password": "pa3"}' -H "Content-Type: application/json"
you will get an error validation response :您将收到错误验证响应:
{"timestamp":"2020-11-07T16:43:51.926+00:00","status":400,"error":"Bad Request","message":"...","path":"/register"}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.