簡體   English   中英

如何加入多個驗證注解

[英]How to join several validation annotations

我有以下注釋來驗證密碼:

@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 {};
}

但是 spring 驗證不承認這個規則。 我將此注釋用作:

@Password
private String password;

如何在不定義ConstraintValidator實例的情況下獲得它?

如果你想使用ConstraintValidator ,你可以這樣做:

創建密碼注釋:

@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 {};

}

然后創建 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;
        }

}

然后將其應用於您的一個字段,請注意,您還可以放置自定義消息:

@Password(message = "....")
private String password;

@Password
private String passwd;

您還可以在適當的方法中重構每個 if 語句(以獲得干凈的代碼):看起來像這樣:

  @Override
  public boolean isValid(String value, ConstraintValidatorContext context) {
        return (notNull(value) && isValidPasswordLength(value) && isValidPasswordValue(value));
     }

更新

由於您不想使用ConstraintValidator ,您的實現看起來不錯,您只需要在模型上添加@Valid以便可以執行級聯驗證並包含spring-boot-starter-validation以確保包含驗證 api並在您的自定義注釋上添加@Constraint(validatedBy = {}) 這是這里的一個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 {}
}

所以當你卷曲時:

curl -X POST http://localhost:8080/register -d '{"username": "rsone", "password": "pa3"}' -H "Content-Type: application/json"

您將收到錯誤驗證響應:

{"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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM