Java Don';t如果@RequestParam required=false,则验证

Java Don';t如果@RequestParam required=false,则验证,java,spring,validation,spring-boot,annotations,Java,Spring,Validation,Spring Boot,Annotations,我已经创建了一个自定义验证器注释,我只想在username不为空时使用它。我有一个端点,其中不需要@RequestParam-String-username,一切都很好。问题在于注释,因为它验证username,而不管是否存在变量。仅当用户名存在时,我才想验证用户名。以下是代码: @RequestMapping(value = "", method = RequestMethod.GET) public ResponseEntity get( @RequestParam(value = "use

我已经创建了一个自定义验证器注释,我只想在
username
不为空时使用它。我有一个端点,其中不需要
@RequestParam-String-username
,一切都很好。问题在于注释,因为它验证
username
,而不管是否存在变量。仅当
用户名
存在时,我才想验证
用户名
。以下是代码:

@RequestMapping(value = "", method = RequestMethod.GET)
public ResponseEntity get( @RequestParam(value = "username", required = false) @ExistAccountWithUsername(required = false) String username) {
    if (username != null) {
        return getUsersByUsername(username);
    }
    return getAllUsers();
}
注释:

@Filled
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ExistAccountWithUsernameValidator.class)
public @interface ExistAccountWithUsername {
  boolean required() default true;
  String message() default "There is no account with such username";
  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}

在自定义验证器中,您只需执行空检查,如下所示:

@Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
    if(value == null)
        return true;
    return someFurtherCheck(value, context);
}
这样,如果为null,则接受它,否则将检查它。 此外,如果您想在null值应返回false的其他地方重用此验证器,您可以在要检查的字段顶部添加一个
@NotNull
,或者在验证器注释中添加参数,规定是否应接受null值

最新的方法如下所示:

@ExistAccountWithUsername
类:

public @interface ExistAccountWithUsername {


String message() default "your message";
Class[] groups() default {};

Class[] payload() default {};

boolean acceptNull() default true;

}
验证器类别:

public class ExistAccountWithUsernameValidator implements ConstraintValidator<ExistAccountWithUsername, String> {

private boolean acceptNull;

@Override
public void initialize(ExistAccountWithUsername constraintAnnotation){
    acceptNull = constraintAnnotation.acceptNull();
}

@Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
    if(value == null)
       return acceptNull;
    return someFurtherCheck(value, context);
}


 }
公共类ExistaCountWithUsernameValidator实现ConstraintValidator{
私有布尔接受空;
@凌驾
public void initialize(ExistAccountWithUsername constraintanotation){
acceptNull=ConstraintAnotation.acceptNull();
}
@凌驾
公共布尔值有效(字符串值、ConstraintValidatorContext上下文)
{
如果(值==null)
返回acceptNull;
返回检查(值、上下文);
}
}

因此,现在当您不想接受此验证器的空值时,只需使用
@ExistAccountWithUsername(acceptNull=false)
而不是
@ExistAccountWithUsername

我发现您可能已经创建了验证注释
@ExistAccountWithUsername
。重用它并将条件添加到方法中


以防我误解您的
@ExistAccountWithUsername
注释。Baeldung的文章中有一个非常详细的指南。

@Nikolas我想在其他情况下也使用这个注释。我添加了带有布尔必填字段的参数,但是我的注释有类似于
@NotNull
@NotBlank
的注释,即使我在自定义验证器中
返回true
,它们也会进行验证。在这种情况下,您可以向@ExistsAccountWithUsername注释添加一个参数,以规定它应该如何处理空值,如我的回答中所述。我将更新它以提供一个代码示例。我更新了答案,现在它应该适合您的用例。我已经这样做了。查看我的更新代码和验证错误。如果
required=false,我必须完全关闭验证,否则它会检查其他“打开”的注释此注释如果不需要
@RequestParam
,并不意味着我应该传递空用户名或空用户名,因为我将获得空指针异常,因此我需要检查
@NotNull
@NotBlank
public @interface ExistAccountWithUsername {


String message() default "your message";
Class[] groups() default {};

Class[] payload() default {};

boolean acceptNull() default true;

}
public class ExistAccountWithUsernameValidator implements ConstraintValidator<ExistAccountWithUsername, String> {

private boolean acceptNull;

@Override
public void initialize(ExistAccountWithUsername constraintAnnotation){
    acceptNull = constraintAnnotation.acceptNull();
}

@Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
    if(value == null)
       return acceptNull;
    return someFurtherCheck(value, context);
}


 }
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
    if (username == null) {
        return true;  // is valid
    } else {
        // ... further validation in case the username is not null
    }
}