我想驗證一個字段birthYear
:「用戶的年齡必須低於50」。JSR-303 - 作爲參數的計算值?
所以我想使用JSR-303註釋驗證這樣的:
@Max(Calendar.getInstance().get(Calendar.YEAR) - 50)
private int birthYear;
但是編譯器說,「屬性值必須是恆定的。」
有沒有辦法以一種簡單的方式來做到這一點?還是有必要爲此實現我自己的驗證器?
我想驗證一個字段birthYear
:「用戶的年齡必須低於50」。JSR-303 - 作爲參數的計算值?
所以我想使用JSR-303註釋驗證這樣的:
@Max(Calendar.getInstance().get(Calendar.YEAR) - 50)
private int birthYear;
但是編譯器說,「屬性值必須是恆定的。」
有沒有辦法以一種簡單的方式來做到這一點?還是有必要爲此實現我自己的驗證器?
正如您的錯誤消息所示,您不能在註釋值中使用表達式,因此您需要使用自定義驗證註釋。
這是比較容易做到這一點:
註釋
@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)
,它應該工作。
問題是註釋參數需要有一個可以在編譯時解析的值,但只能在運行時解析調用Calendar.getInstance().get(Calendar.YEAR)
因此編譯器錯誤。
您在這種情況最好寫在二傳手邏輯驗證邏輯,就像
public void setBirthYear(int year){
if(Calendar.getInstance().get(Calendar.YEAR) - year < 50) {
{
throw IllegalAgumentException()
}
this.birthYear = year;
}
替代的東西是,你可以寫一個自定義的JSR 303註解像@VerifyAge(maxAge=50)
然後在可以檢查該值是否小於50.
有關如何編寫自定義驗證註釋的詳細信息,請參閱http://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html/validator-customconstraints.html。
如果您使用的是Spring框架,那麼您可以使用Spring表達式語言(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;
的
可能重複[用於註釋屬性的值Min.value必須是一個常量表達式(http://stackoverflow.com/questions/16744067/the-value-for-annotation-attribute-min-value-must-be-a-constant-expression) – BalusC
是的,你是對的。我無法谷歌它。 – StaNov
但仍然有辦法做到這一點嗎?比實現自定義驗證器更容易? – StaNov