我希望以一种方式验证字段birthYear
:“用户的年龄必须低于50。”
所以我想像这样使用JSR-303注释验证:
@Max(Calendar.getInstance().get(Calendar.YEAR) - 50)
private int birthYear;
但是编译器说“属性值必须是常量。”
有没有办法以简单的方式做到这一点,比如这个?或者是否有必要为此实现我自己的验证器?
答案 0 :(得分:1)
问题是注释参数需要有一个可以在编译时解析的值,但是对Calendar.getInstance().get(Calendar.YEAR)
的调用只能在运行时解析,因此编译错误。
在这种情况下,最好在设置器逻辑中编写验证逻辑,例如
public void setBirthYear( int year){
if( Calendar.getInstance().get(Calendar.YEAR) - year < 50) {
{
throw IllegalAgumentException()
}
this.birthYear = year;
}
另一种方法是你可以编写一个类似@VerifyAge(maxAge=50)
的自定义JSR 303 Annotation,然后在注释的处理程序中检查该值是否小于50.
有关如何编写自定义验证注释的详细信息,请参阅http://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html/validator-customconstraints.html。
答案 1 :(得分:0)
正如您的错误消息所示,您不能在注释值中包含表达式,因此您需要使用自定义验证注释。
这样做相对容易:
注释
@Constraint(validatedBy = AgeConstraintValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface MaxAge {
/**
* The age against which to validate.
*/
int value();
String message() default "com.mycompany.validation.MaxAge.message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
约束验证器
public class AgeConstraintValidator implements ConstraintValidator<MaxAge, Integer> {
private int maximumAge;
@Override
public void initialize(MaxAge constraintAnnotation) {
this.maximumAge = constraintAnnotation.value();
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return value.intValue() <= this.maximumAge;
}
}
然后,您可以使用@MaxAge(50)
注释您的字段,它应该可以正常工作。
答案 2 :(得分:0)
如果您正在使用Spring Framework,那么您可以使用Spring Expression Language(SpEL)。我写了一个小型库,提供基于SpEL的JSR-303验证器。看看https://github.com/jirutka/validator-spring。
使用此库,您可以像这样编写验证:
@SpELAssert("#this < T(java.util.Calendar).getInstance().get(T(java.util.Calendar).YEAR) - 50")
private int birthYear;
然而,获得当年的代码相当难看,不是吗?让我们把它变成一个帮手类吧!
public class CalendarHelper {
public static int todayYear() {
return Calendar.getInstance().get(Calendar.YEAR);
}
}
然后你可以这样做:
@SpELAssert(value="#this < #todayYear() - 50", helpers=CalendarHelper.class)
private int birthYear;