2011-02-08 78 views
6

我正在使用JSR303並創建了一個類級約束,該約束將表單中的密碼與其確認進行比較,我將在這裏命名@SameAs約束。理想情況下,我希望將約束與預期目標(confirmPassword)相關聯,但顯然封閉bean不可用於提取密碼prop。 - 因此是類級約束。JSR303:嘗試自定義約束衝突與類級關係約束驗證器中的子路徑相關聯

我已經感興趣地閱讀了其他文章,演示瞭如何利用類級約束來驗證關係,但找不到任何解釋如何將約束違規定製爲與子路徑關聯的東西,在這種情況下,在關係中的兩個領域。

我的問題如下:如何將違反約束的消息與'confirmPassword'字段而不是頂級對象相關聯?我曾嘗試使用javax.Validator.validate(目標上下文)的情況下放慢參數,但添加驗證了@SameAs內的節點會導致在級聯下一個約束的例外(試圖提取confirmPassword - >訂單號碼屬性作爲結果,而不是訂單 - > orderNumber)。

因爲我已經通過創建額外的屬性存儲被拔光了web層在靠近confirmPassword投入現場使用的約束消息使出一個醜陋的雜牌組裝電腦的那一刻。

當然我在這裏失去了一些東西....請參閱任何評論

@Constraint(validatedBy = { SamePwdAsValidator.class}) 
public interface SamePwdAs {//... 
} 

//Using passwords in an order doesn't make sense - only for demo purpose 
@SamePwdAs(message = "Password and confirmation must match" ...) 
public class Order { 

    @NotNull 
    @Size(....) 
    String pwd; 

    //where I would really like to use @SameAs, and associate a violation 
    String pwdConfirm; 

    @NotNull (...) 
    @Pattern (....) 
    String orderNumber; 

    //...getters/setters 
} 

public class SamePwdAsValidator implements javax.validation.Validator { 
//... 
    public boolean isValid(Object target, ValidationContext ctx) { 
    String tgt = target.getPwd(), other = target.getPwdConfirm() 
    boolean isValid = tgt.equals(other); 

    if (!isValid) { 
     //try to configure the context subpath for pwdConfirm to associate this constraint violation with: I tried 
     //ctx.addNode('pwdConfirm').addConstraintViolation() which doesn't work, as the next validator will 
     //bump into trying to extract Order.pwdConfirm.orderNumber and throw a NoPropertyFoundException or the like 
    } 

    return isValid; 
} 

回答

5

我要去給2個回答下面的例子

感謝。

答1,其努力回答你的問題:

我用一個工具方法,像這樣:

public static final void recreateConstraintViolation(ConstraintValidatorContext constraintValidatorContext, String errorCode, String fieldName) { 
     constraintValidatorContext.disableDefaultConstraintViolation(); 
     constraintValidatorContext.buildConstraintViolationWithTemplate(errorCode). 
     addNode(fieldName).addConstraintViolation(); 

} 

,然後在你的驗證器,你比較兩個密碼:

if (!isValid) { 
    for (String fieldName : fieldNames) { 
     CustomConstraintUtils.recreateConstraintViolation(constraintValidatorContext, "password.password2.mismatch", fieldName); 
    } 
    return false; 
} 

回答2

我建議你使用像Spring Security的安全框架,採取密碼匹配的小心,因爲我相信你的用例是處理用戶登錄。