Javax Validation自定义验证器如何屏蔽默认额外错误消息?
问题描述
我有一个Answer对象,它可以存储多种类型的答案(邮箱、手机号、姓名等),所有类型的答案文本都存在单个value参数里。现在我写了一个自定义验证器处理验证逻辑,但遇到了问题:当验证失败时,除了我通过ConstraintValidatorContext添加的自定义消息外,还会多出一条空的默认消息,这条消息来自注解里默认的空字符串message()。我想只保留自定义消息,屏蔽这条默认的验证违规消息,环境是纯Java(无Spring)。
我的代码实现如下:
注解定义
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = AnswerValidator.class) public @interface ValidateAnswerEmail { String message() default ""; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
验证器实现
public class AnswerValidator implements ConstraintValidator<ValidateAnswerEmail, Answer> { @Override public boolean isValid(Answer answer, ConstraintValidatorContext context) { boolean success = true; // 这里是自定义的验证逻辑(validation #1、#2、#3) // 比如验证不通过时,添加自定义消息: // context.buildConstraintViolationWithTemplate("Email address: " + answer.getValue() + " is not a valid email address") // .addConstraintViolation(); // success = false; return success; } }
错误消息示例
Constraint violations: (1) Kind: PARAMETER parameter index: 0 message: Email address: some@User@gmail.com is not a valid email address root bean: org.company.crs.api.AnswerResource@42475403 property path: updateAnswer.arg0 constraint: @org.company.crs.validator.ValidateAnswerEmail(message="", groups={}, payload={}) (2) Kind: PARAMETER parameter index: 0 message: root bean: org.company.crs.api.AnswerResource@42475403 property path: updateAnswer.arg0 constraint: @org.company.crs.validator.ValidateAnswerEmail(message="", groups={}, payload={})
解决方案
要屏蔽默认的验证消息,只保留自定义添加的消息,你需要在isValid方法中调用ConstraintValidatorContext的disableDefaultConstraintViolation()方法,这个方法会关闭默认的违规消息生成。
修改后的验证器代码如下:
public class AnswerValidator implements ConstraintValidator<ValidateAnswerEmail, Answer> { @Override public boolean isValid(Answer answer, ConstraintValidatorContext context) { boolean success = true; // 先禁用默认的违规消息 context.disableDefaultConstraintViolation(); // 执行自定义验证逻辑 if (!isValidEmailFormat(answer.getValue())) { // 添加自定义消息 context.buildConstraintViolationWithTemplate("Email address: " + answer.getValue() + " is not a valid email address") .addConstraintViolation(); success = false; } // 其他验证逻辑... return success; } // 示例邮箱格式验证方法 private boolean isValidEmailFormat(String email) { // 这里实现具体的邮箱格式校验逻辑 return email != null && email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"); } }
原理说明
disableDefaultConstraintViolation()方法会告诉Bean Validation框架,不要根据注解中的message()生成默认的违规消息。- 之后你通过
buildConstraintViolationWithTemplate()添加的自定义消息会成为唯一的验证失败消息,不会再出现那条空的默认消息。
内容的提问来源于stack exchange,提问作者Tabs
相关产品推荐
相关产品推荐

