我已经实现了自定义注释 @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/