java - Bean验证: Complex message value resolution - but how?

标签 java bean-validation

我编写了一个名为 @Year 的自定义约束,它检查 Date 是否出现在某一年。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Constraint(validatedBy = YearCheck.class)
public @interface Year {

  String message() default "{year.message}";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

  /**
   * The lower year. If not specified then no upper boundary check is performed.<br>
   * Special values are:
   * <ul>
   * <li>{@link TimeUtil#NOW} for the current year
   * </ul>
   */
  String min() default "";

  /**
   * The upper year. If not specified then no upper boundary check is performed.<br>
   * Special values are:
   * <ul>
   * <li>{@link TimeUtil#NOW} for the current year
   * </ul>
   */
  String max() default "";
}

ValidationMessages.properties 包含以下内容:

year.message = must be a year between {min} and {max}

如您所见,minmax 是字符串,因为 TimeUtil.NOW (包含 "now") 表示以当前年份进行比较。

另外,如果没有指定minmax,则表示对应的值为无穷大

所以,问题是,例如对于 min:我如何检查 min 是否已设置以及是否不是数字("""now") 如何设置一个值,然后将其插入到消息中?

例如@Year(min=1900,max=TimeUtil.NOW)应该生成消息

must be a year between 1900 and 2013

我已经阅读了 stackoverflow 上的一些答案,阅读了文档,但我不确定 a) 是否可能 b) 我需要在约束实现或自定义 MessageInterpolator 中执行此操作.

最佳答案

How can I check whether min has been set and if's not a number

您可以在 ConstraintValidator 实现的 initialize() 方法中访问注释属性。

how can I set a value which will then be inserted into the message?

您不能直接执行此操作,但您可以使用传递的 ConstraintValidatorContext 在 validator 的 isValid() 方法中自行创建消息。

您的 validator 可能如下所示:

public class YearValidator implements ConstraintValidator<Year, String> {

    private Date min;
    private Date max;

    @Override
    public void initialize(Year constraintAnnotation) {
        if(constraintAnnotation.min().equals("")) {
            min = getMinimumDate();
        }
        else if(constraintAnnotation.min().equals(TimeUtil.NOW)) {
            min = getCurrentYear();
        }
        else {
            min = getYearFromString(constraintAnnotation.min());
        }

        //same for max()
}

    @Override
    public boolean isValid(Date value, ConstraintValidatorContext context) {
        if(value == null) {
            return true;
        }

        if(value.before(min) || value.after(max)) {

            context.disableDefaultConstraintViolation();

            //load/create the error message and set min and max in it
            String template = getTemplate(min, max);

            context
                .buildConstraintViolationWithTemplate(template)
                .addConstraintViolation();

            return false;
        }

        return true;
    }
}

关于java - Bean验证: Complex message value resolution - but how?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14336310/

相关文章:

java - 如何创建具有指定宽度和显示所有文本所需的尽可能小的高度的 JTextArea?

java - Hive GenericUDF 错误 - RuntimeException typeInfo 不能为 null

java - 使用 Bean 验证时防止内部服务器错误

java - Spring Boot Web 应用程序如何验证另一个字段所需条件的表单字段?

java - Java 中的 HttpPut 文件上传 - 覆盖 TrustStrategy : Is there a "better/safer" way?

java - 如何在 swagger codegen 中注入(inject)自定义 spring 验证?

Java:无法访问变量?

java - Spring Data JPA JpaRepository.save(Iterable..) - 没有 javax.validation? (实体上的注释未经过验证)

java - 将 JSR-303 验证错误转换为 Spring 的 BindingResult

java - 使用 JSR-303 的派生类中更具体的约束