4

ロケールをキー、文字列を値として、ローカライズされた値に Map を使用します。必須フィールドについては、少なくとも必要なロケールが設定されていること、または少なくともいくつかの値が設定されていることを確認する必要があります。そのような Map フィールドと対応するバリデーターで使用される検証アノテーションを実装しました。問題は、欠損値を報告するにはどうすればよいかということです。フィールド エラー/値をバインドするために UI で使用されるプロパティ パスは、毎回間違っています。

// Domain object:
@LocalizationRequired
private Map<Locale, String> field;


// LocalizationRequiredValidator:
public boolean isValid(Map<Locale, String> map, ConstraintValidatorContext context) {
    if (requiredLocales.isEmpty()) {
        // Check that there exists any not null value
    } else {
        context.disableDefaultConstraintViolation();
        boolean valid = true;
        for (Locale requiredLocale : requiredLocales) { 
            if (map.get(requiredLocale) == null) { // e.g. fi
                valid = false;
                context.buildConstraintViolationWithTemplate("LocalizationRequired")
                // These end up in wrong property path:
                // .addNode(requiredLocale) 
                //    --> field.fi
                // .addNode("[" + requiredLocale + "]") 
                //    --> field.[fi]
                // .addNode(null).addNode(requiredLocale).inIterable() 
                //    --> field.fi
                // .addNode(null).addNode(null).inIterable().atKey(requiredLocale)
                //   --> field
                .addConstraintViolation();
            }
        }
        return valid;
    }
}

このエラーの正しいパスは「field[fi]」ですが、インデックス付きのサブ プロパティにしかアクセスできないようです。この場合、オブジェクト自体にインデックスが付けられます。Hibernate Validator を使用しています。

4

2 に答える 2

3

要素レベルでインデックス付きフィールドのエラーを報告する方法を見つけることができませんでした。- これは仕様で見落とされていませんか?

これが私がしたことです:

Map の代わりに、サポートされているすべてのロケール (LocalizedString(String fi、String en など) の実際のフィールドを持つ「埋め込み可能な」Bean を使用しました。その後、次のような違反が報告されました。

context.buildConstraintViolationWithTemplate("LocalizationRequired")
.addNode(requiredLocale)
.addConstraintViolation();

これは、サポートされている言語の事前定義されたセットがあるため、私たちの場合は実現可能ですが、任意のインデックスを持つインデックス付きフィールドには拡張できません。

さらに、SpringLocalValidatorFactoryBeanまたは Hibernate Validator のいずれかが、埋め込み可能オブジェクトの検証を適切にサポートしていません。同じコンポーネントがさまざまな検証要件でさまざまな場所で使用されるため@Valid、コンポーネント自体内で実際の検証アノテーションを使用することはできません。少なくとも、検証グループのサポートなしでは使用できません@Valid

SpringLocalValidatorFactoryBeanまたは Hibernate Validatorの問題は、報告された誤ったネストされたフィールド (「field.fi」) の値ではなく、invalidValueConstraintViolationが LocalizedString (「フィールド」) であることです。幸いなことに、これは LocalValidatorFactoryBean.processConstraintViolations「ConstraintViolation からの無効な値を持つカスタム FieldError 登録」を削除してオーバーライドし、単にエラーを報告することで解決できます。

errors.rejectValue(field, errorCode, errorArgs, violation.getMessage());

このようにして、Spring はinvalidValueusing given を解決しfieldます。

于 2012-08-09T13:46:40.800 に答える
0

これはかなり興味深い質問です。今は自分でテストする時間がありません :( が、ここにいるこの男 :

コレクションの検証

要素のコレクションを検証できるようです。したがって、マップの代わりにコレクションに切り替えると (かなり簡単なはずです)、たとえば次のようになります。

 class LocaleToString {
      private Locale locale;
      private String language;
 }

 @LocalizationRequired
 List<LocaleToString> locales;

あなたはあなたが望むものを達成できるはずです。

于 2012-08-06T05:59:29.657 に答える