如何从约束描述符手动评估hibernate验证器消息模板?

时间:2017-07-12 21:21:16

标签: java javadoc hibernate-validator

我成功使用Hibernate Validator验证请求POJO。 getter上的注释有点自我记录,所以有人可以仔细阅读生成的javadoc以查看约束条件。

我觉得这对于有效的文档来说还不够好。我正在尝试编写一个Javadoc自定义Taglet,它可以对当前包含的类进行内省,并在类中为属性构建一个HTML表。

我实际上已经能够获得每个约束属性的ConstraintDescriptor。我希望能够做的是插入“messageTemplate”以生成可读的字符串。

例如,如果属性具有@Size注释,我可以找到有关此ConstraintDescriptor的信息,并且“messageTemplate”属性的值为“{javax.validation.constraints.Size.message}” 。我需要得到的信息是“必须在X和Y之间”(或类似的东西)。如果该字符串具有指定的实际“min”和“max”值,那将是很好的,但如果它说“必须在{min}和{max}之间......”我会很好。

似乎唯一接近的是ValidatorFactory的“messageInterpolator”属性,以及它的“interpolate()”方法。问题是,除了消息模板之外,该方法还需要“Context”对象。这当然是可以理解的,因为它必须从类似的东西获得像“min”和“max”这样的参数,但我不明白我必须在这里提供什么。

到目前为止,我的代码看起来有点像这样:

            ValidatorFactory    validatorFactory    =
                Validation.
                byProvider(HibernateValidator.class).
                providerResolver(new HibernateValidatorProviderResolver()).
                configure().
                externalClassLoader(getClass().getClassLoader()).
                messageInterpolator(new ResourceBundleMessageInterpolator(
                        new PlatformResourceBundleLocator(ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES),
                        true, buildExpressionFactory())).
                buildValidatorFactory();

        Validator   validator   = validatorFactory.getValidator();

        BeanDescriptor  constraintsForClass = validator.getConstraintsForClass(clazz);
        System.out.println("constraintsForClass[" + constraintsForClass +
                           "] hasConstraints[" + constraintsForClass.hasConstraints() + "]");
        if (constraintsForClass.hasConstraints()) {
            for (ConstraintDescriptor<?> constraintDescriptor : constraintsForClass.getConstraintDescriptors()) {
                System.out.println("constraintDescriptor[" + constraintDescriptor + "]");
                emitTableRow(sb, "", constraintDescriptor);
            }
        }
        for (PropertyDescriptor propertyDescriptor : constraintsForClass.getConstrainedProperties()) {
            System.out.println("propertyDescriptor[" + propertyDescriptor +
                               "] name[" + propertyDescriptor.getPropertyName() + "]");
            for (ConstraintDescriptor<?> constraintDescriptor : propertyDescriptor.getConstraintDescriptors()) {
                System.out.println("constraintDescriptor[" + constraintDescriptor +
                                   "] mt[" + constraintDescriptor.getMessageTemplate() + "]");
                String  interpolatedStr = validatorFactory.getMessageInterpolator().interpolate(constraintDescriptor.getMessageTemplate(), null);
                System.out.println("interpolatedStr[" + interpolatedStr + "]");

如您所见,我目前正在将“null”作为第二个参数传递给“interpolate()”,这会导致NPE为“org.hibernate.validator.internal.engine.messageinterpolation.ParameterTermResolver.getVariable(Context, String)”。

1 个答案:

答案 0 :(得分:0)

您可以尝试传入MessageInterpolator.Context的虚拟实现,它返回您手中的描述符,并为验证值返回null。