2

Spring MVC 3 と JSR 303 を使用しています。さまざまなタイプの Bean を含むフォーム バッキング オブジェクトがあります。リクエスト パラメータの値に応じて、検証して保存する Bean を選択する必要があります。@Valid検証する Bean は実行時までわからないため、検証には使用できません。

コントローラーにa を注入できましたが、それを使用して Bean を検証し、「Spring の方法」でjavax.validation.Validatorエラーを a に保存する方法がわかりません。BindingResult/Error

initBinderリクエスト マッピングのため、メソッドではなくハンドラー メソッドで行う必要があります。

[編集]

私が抱えている問題validate(Object, Errors)は、ネストされた Bean を認識しないことです。検証する Bean は、foo.getBar().getBean() を介してアクセスされます。ここで、foo はフォーム バッキング オブジェクトです。するとvalidate(foo.getBar().getBean(), errors)、次のエラー メッセージが表示されます。

JSR-303 validated property 'property-name' does not have a corresponding accessor for Spring data binding

誰かが前にこのようなことをしたことがありますか? ありがとう。

4

3 に答える 3

5

うん、あなたが探している魔法のクラスはorg.springframework.validation.beanvalidation.SpringValidatorAdapter

このクラスには javax.validation.Validator が注入され、その名前が示すように、出力を使い慣れたErrorsオブジェクトに戻すためのコードが含まれています。@Validこれは、メソッド パラメーターを設定した ときに処理を行うために内部で使用されているものです。

LocalValidatorFactoryBeanDispatcher サーブレットに明示的に追加することで、それらを直接取得できます。そのインスタンスを標準 Spring Validator インターフェースのインスタンスとして注入し、「jsr-303 以前」の Spring 検証プロバイダーと同じように使用します。

于 2010-11-15T23:28:30.960 に答える
4

推測ですが、試したことはありますか

 errors.pushNestedPath("bar.bean"); // Path to the nested bean
 validate(foo.getBar().getBean(), errors)
 errors.popNestedPath();

これBindingResultは通常、ネストされたBeanの検証に使用される方法です。

于 2010-11-16T12:49:17.697 に答える
0

私がこれを行った方法は、標準の JSR-303 バリデーター (既に注入しているものは何でも) を使用して違反 (つまりSet<ConstraintViolaion<T>>)を取得することです。

次に、LocalValidatorFactoryBean 内のコードと同様のコードを使用して、これらの違反と Spring エラーの間で変換します。

public static <T> void convert(Errors errors, Collection<ConstraintViolation<T>> violations) {
        for (ConstraintViolation<?> violation : violations) {
            String field = violation.getPropertyPath().toString();
            FieldError fieldError = errors.getFieldError(field);
            if (fieldError == null || !fieldError.isBindingFailure()) {
                errors.rejectValue(field, violation.getConstraintDescriptor().getAnnotation().annotationType()
                        .getSimpleName(), getArgumentsForConstraint(errors.getObjectName(), field, violation
                        .getConstraintDescriptor()), violation.getMessage());
            }
        }
    }

    private static Object[] getArgumentsForConstraint(String objectName, String field,
            ConstraintDescriptor<?> descriptor) {
        List<Object> arguments = new LinkedList<Object>();
        String[] codes = new String[] { objectName + Errors.NESTED_PATH_SEPARATOR + field, field };
        arguments.add(new DefaultMessageSourceResolvable(codes, field));
        arguments.addAll(descriptor.getAttributes().values());
        return arguments.toArray(new Object[arguments.size()]);
    }
于 2010-11-16T09:15:36.627 に答える