4

私はすべての検証制約を共通のライブラリに集めていました。jar のルートにValidationMessages_it.propertiesファイルを配置しました。このライブラリを jsf 2 war プロジェクトに配置すると、すべての検証メッセージが正しく表示されます。ValidationMessages_it.propertiesただし、戦争アーティファクトに別のものを入れると問題が発生します。この場合、{library.message_key}文字列が表示されます。

Bean Validation は戦争で適切なプロパティ ファイルを見つけ、ライブラリでそれを考慮していないと思います。どうすれば解決できますか?

カスタム制約を含むライブラリ commons.jar があります。これらの制約にメッセージを設定するためにValidationMessages_it.properties、このライブラリのルートにを追加しました

commons.jar
    |
    + library
    |   |
    |   + CustomConstraint.class
    |
    + ValidationMessages_it.properties

ValidationMessages_it.properties

library.custom=Questo è l'errore di cui parlavo

CustomConstraint.java

@Pattern( regexp = "[a-z]", message = "{library.custom}" )
@Constraint( validatedBy = {} )
@Documented
@Target( { ElementType.METHOD, ElementType.FIELD } )
@Retention( RetentionPolicy.RUNTIME )
public @interface CustomConstraint {
    String message() default "C'è un errore";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

PS: メッセージ キーは message() ではなく @Pattern アノテーションにあることに注意してください。これは間違いのように思えるかもしれませんが、そうでなければ機能しません!

commons.jarその後、これを自分の Web アプリ プロジェクト (jsf/mojarra 2.1) で使用したいと考えています。すべて正常に動作します。表示されるエラー メッセージは「Questo è l'errore di cui parlavo」です。

ValidationMessages_it.propertiesしかし、ここで、webapp で新しい検証制約を定義するとします。そのため、 inWEB-INF/classesフォルダーを追加して、これらの制約の翻訳を提供したいと考えています。この場合、表示されるエラー メッセージは「{library.custom}」です。

したがって、BV(またはjsf?)は戦争でバンドルを見つけ、commons.jarでそれを考慮していないと思います。フォルダに存在するキーlibrary.customが見つからないため、文字通り返されます。ValidationMessages_it.propertiesWEB-INF/classes{library.custom}

例 2

共有ライブラリの Bean Validation 制約に基づいて、私のパッケージ構造は正しいようです。問題を示すために、単純な Web アプリをアップロードしました。

Glassfish 3.1.2、JBoss AS 7.1.1、Geronimo 3.0.0 で webapp をテストしました

Glassfish と JBoss の動作は同じです。Geronimo では、もう少しうまく機能します。

4

2 に答える 2

4

デフォルトでは、複数の JAR/WAR/etc. ファイルにはまったく同じ名前のリソース バンドル ファイルが含まれており、そのうちの 1 つだけがバリデータ メッセージに使用されます。これが問題です:commons.jarとアプリケーション WAR の両方に name のリソースが含まれていますValidationMessages_it.properties

2015 年 7 月にリリースされた Hibernate Validator 5.2 では、異なる JAR ファイルから同じ名前のすべてのリソース バンドルを集約するためのサポートが追加されました。この機能はデフォルトで無効になっており、 org.hibernate.validator.resourceloading.PlatformResourceBundleLocatorで設定できます。

例:

PlatformResourceBundleLocator resourceBundleLocator =
    new PlatformResourceBundleLocator(ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, null, true);

Validator validator = Validation.byProvider(HibernateValidator)
    .configure()
    .messageInterpolator(new ResourceBundleMessageInterpolator(resourceBundleLocator))
    .buildValidatorFactory()
    .getValidator();

Java 構成を使用した Spring プロジェクトの同等のコード:

@Bean
public LocalValidatorFactoryBean validator() {
    PlatformResourceBundleLocator resourceBundleLocator =
            new PlatformResourceBundleLocator(ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, null, true);

    LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
    factoryBean.setMessageInterpolator(new ResourceBundleMessageInterpolator(resourceBundleLocator));
    return factoryBean;
}
于 2015-10-30T18:31:55.497 に答える
3

あなたの場合の解決策は、前述のAggregateResourceBundleLocatorだと思います。ただし、プロパティ ファイルに同じ名前を付けることはできません。内部的にResourceBundle#getBundleが呼び出され、単一のResourceBundleが返されます。同じ名前のプロパティ ファイルを結合/マージするという概念はありません。

編集1

それを行う標準的な方法については、残念ながらありません。Bean Validation 1.1 ( BVAL-252 ) には、制約ライブラリを提供する機能に対処するための未解決の問題がありますが、まだ何も決定されておらず、メッセージ補間にも対処する必要があります。たぶん、あなたはそれがどのように機能するべきかについて考えを持っています。その場合は、専門家グループに提案を提供してください。beanvalidation.org を確認してください

于 2012-07-26T14:22:51.910 に答える