java - 未执行方法参数上的自定义注释

标签 java validation annotations

我已经实现了自定义注释 @Password 来对我的方法 setPassword() 的参数执行验证。注释定义如下:

// Password.java
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import javax.validation.*;

@Target({METHOD, FIELD, PARAMETER, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
@Documented
public @interface Password {
    String message() default PasswordValidator.message;
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

validator 的当前实现是这样的:

// PasswordValidator.java
package utils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class PasswordValidator implements ConstraintValidator<Password, String> {

    /* Default error message */
    final static public String message = "error.invalid.password";

    /**
    * Validator init
    * Can be used to initialize the validation based on parameters
    * passed to the annotation.
    */
    public void initialize(Password constraintAnnotation) {
        System.out.println("in initialize()");
    }

    public boolean isValid(String string, ConstraintValidatorContext constraintValidatorContext) {
        System.out.println("in isValid()");
        return false;
    }
}

请注意,在当前实现中,isValid() 始终返回 false。原因很快就会显而易见。

我对 validator 的使用是在 User 类中。为简洁起见,我不会在这里发布整个源代码,但相关部分是:

package models;

import utils.Password;
// other imports omitted


@Entity
@Table(name = "users", schema="public")
public class User {

    @Required
    private String password;

    ...

    public void setPassword(@Password String clearPassword) {
        try {
            this.password = HashHelper.createPassword(clearPassword);
        } catch (AppException e) {
            e.printStackTrace();
        }
    }

    ...
}

基本思想是我使用 User 类为用户存储散列密码,但在设置散列密码之前,我(想)对未散列密码(即 clearPassword).

我遇到的问题是没有进行此验证。在当前的实现中,它应该(根据我的理解)总是抛出一个 ConstraintViolationException 因为 isValid() 总是返回 false,但事实并非如此。

我已经通过(在应用程序的另一部分)调用以下内容来检查注释是否附加到方法参数:

Method method = user.getClass().getMethod("setPassword", new Class[] { String.class });
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
System.out.println(method.getName() + ": " + parameterAnnotations[0][0]);

产生以下输出:

setPassword:@utils.Password(message=error.invalid.password, payload=[], groups=[])

所以这告诉我注释正在应用于方法参数。但是我不明白为什么在我实际调用该方法时没有得到 ConstraintViolationException。我也从来没有看到我添加到这些方法中的输出“in initialize()”或“in isValid()”,以检查它们是否被触发.

作为另一个测试,我还在User.class中的成员变量password上添加了@Password注解。这会导致 ConstraintViolationException 按预期抛出,例如当我尝试保留一个 User 对象时。

谁能解释为什么方法参数上的注释不能正常工作?提前致谢!

最佳答案

我认为您在 Password 注释中缺少此声明:

ConstraintTarget validationAppliesTo() default ConstraintTarget.IMPLICIT;

来自文档:

validationAppliesTo is used at constraint declaration time to clarify what the constraint targets (i.e. the annotated element, the method return value or the method parameters).

The element validationAppliesTo must only be present for constraints that are both generic and cross-parameter, it is mandatory in this situation. A ConstraintDefinitionException is raised if these rules are violated.

The type of the validationAppliesTo parameter is ConstraintTarget. The default value must be ConstraintTarget.IMPLICIT.

关于java - 未执行方法参数上的自定义注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32210488/

相关文章:

jquery - 将信用卡验证添加到我的付款表单

Java 运行时相当于使用 javax Processor/google @AutoService 进行注释处理

java - 子查询中IN子句的Hibernate Criteria等效项?

java - Magento catalogCategoryAttributeList SOAP API 调用不返回所有属性

java - 如何检查 Java 字符串中的每个值?

validation - HTTP POST 中用于数据验证的 HTTP 状态代码和响应主体

java - Lombok 减慢大型项目中的构建过程

在获得焦点时启动 WPF 验证

java - Spring Autowiring 不适用于安全配置

swift - 如何从具有多个图钉的 map View 中删除一个图钉