6

私は JSR303 を使用しており、パスワードとその確認をフォームで比較するクラスレベルの制約を作成しました。ここでは、これを @SameAs 制約と名付けます。理想的には、制約を意図したターゲット (confirmPassword) に関連付けたいと思っていましたが、明らかに、囲んでいる Bean はパスワード プロパティを抽出するために使用できません。- したがって、クラスレベルの制約。

関係を検証するためにクラスレベルの制約を活用する方法を示す他の投稿を興味深く読みましたが、制約違反をカスタマイズしてサブパスに関連付ける方法を説明するものは何も見つかりません。この場合、2 つのフィールドの 1 つです。関係で。

私の質問は次のとおりです。制約違反からのメッセージを、最上位オブジェクトではなく「confirmPassword」フィールドにどのように関連付けますか? javax.Validator.validate( target, context) のコンテキスト パラメータを使用しようとしましたが、@SameAs のバリデータ内に Node を追加すると、カスケードの次の制約で例外が発生します (confirmPassword -> orderNumber プロパティを抽出しようとしています)。 order -> 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;
}
4

1 に答える 1

6

私は2つの答えを与えるつもりです。

Answer 1、あなたの質問に答えようとします:

次のようなユーティリティメソッドを使用します。

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

}

次に、バリデータで 2 つのパスワードを比較します。

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

答え 2

ユースケースはユーザーのログオンを扱っていると思われるため、パスワードの一致を処理するためにSpring Securityのようなセキュリティフレームワークを使用することをお勧めします。

于 2011-06-14T15:55:43.650 に答える