我在 bean 中的一个属性上使用了两个验证注释:
@NotEmpty(message = "{name.required}")
@Pattern(regex = "^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$", message = "{invalid.name}")
private String name;
如果我将名称留空,则会收到两个错误,但我只想要第一个错误消息(如果第一个条件发生,则显示其错误消息,然后跳过第二个条件)。
我在 bean 中的一个属性上使用了两个验证注释:
@NotEmpty(message = "{name.required}")
@Pattern(regex = "^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$", message = "{invalid.name}")
private String name;
如果我将名称留空,则会收到两个错误,但我只想要第一个错误消息(如果第一个条件发生,则显示其错误消息,然后跳过第二个条件)。
如果出现第一个条件,则显示其错误消息,然后跳过第二个条件
这可以通过创建复合约束并使用 @ReportAsSingleViolation 元约束对其进行注释来完成。
用户名.java
@ReportAsSingleViolation
@NotEmpty
@Pattern(regexp="^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$")
@Constraint(validatedBy = {})
public @interface UserName {
String message() default "invalid userName!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
参考3.2。约束组合
接受的答案不像您预期的那样工作。只有当您想列出整个组合链中的所有错误时,确定约束组合才是好的。如果您想提前退出第一个验证错误,则它不起作用。
say The docs for @ReportAsSingleViolation
say The error reports of each individual compose constraint are ignored。
使用接受示例
@ReportAsSingleViolation
@NotEmpty
@Pattern(regexp="^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$")
@Constraint(validatedBy = {})
public @interface UserName {
String message() default "invalid userName!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
这意味着您将收到UserName
注释的默认消息错误,即“无效的用户名!” 即使@NotEmpty 首先失败....
我必须说,Java bean 验证实现者对这种设计的糟糕程度感到非常震惊。如果您返回完全不相关的消息,那么进行组合验证绝对没有意义。它应该首先失败并返回实际失败的验证的相应错误!。无论如何,如果没有大量丑陋的黑客,就没有办法做到这一点。如此简单的验证任务变成了一场噩梦。0_o
我的解决方案是不编写验证,只需创建 1 个验证并自己实施。它不是干的,但至少很简单。
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface Password {
String message() default "{com.example.Password.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
public class PasswordValidator implements ConstraintValidator<Password, String> {
private Pattern twoDigitsPattern;
public void initialize(Password constraint) {
twoDigitsPattern = Pattern.compile("(.*[\\d]){2}");
}
public boolean isValid(String password, ConstraintValidatorContext context) {
context.disableDefaultConstraintViolation();
if (password == null) {
context.buildConstraintViolationWithTemplate("{javax.validation.constraints.NotNull.message}")
.addConstraintViolation();
return false;
}
if (password.length() < 5 || password.length() > 10) {
context.buildConstraintViolationWithTemplate("must be between 5 to 10 characters")
.addConstraintViolation();
return false;
}
if (!twoDigitsPattern.matcher(password).matches()) {
context.buildConstraintViolationWithTemplate("must contain 2 digits between [0-9]").addConstraintViolation();
return false;
}
return true;
}
}