ValidationMessages.properties文件之间的冲突

时间:2012-07-22 09:42:10

标签: java bean-validation

我用来收集公共库中的所有验证约束。在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

Validation_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: 请注意,消息键位于@Pattern注释而不是message(),这似乎是一个错误,但否则它永远不会有效!

之后我想在我的web应用程序项目中使用这个commons.jar(jsf / mojarra 2.1)。一切正常。显示的错误消息是Questoèl'erroredi cui parlavo

但现在假设我在webapp中定义了新的验证约束,所以我想通过在WEB-INF / classes文件夹中添加ValidationMessages_it.properties来为这些约束提供翻译。在这种情况下,显示的错误消息是 {library.custom}

所以我认为BV(或jsf?)在战争中找到了捆绑,并没有考虑commons.jar中的捆绑。它在位于WEB-INF / classes文件夹中的ValidationMessages_it.properties中找不到密钥 library.custom ,因此返回 {library.custom}

编辑2

为了更好地理解哈代的答案,我打开了另一个问题来验证我的假设是否正确:Bean Validation constraints in a shared library

编辑3

基于上述问题,我的包结构似乎是正确的。我上传了一个简单的网络应用程序来显示问题:

我在Glassfish 3.1.2,JBoss AS 7.1.1,Geronimo 3.0.0

中测试了webapp

Glassfish和Jboss具有相同的行为。在Geronimo中它可以更好地工作。

2 个答案:

答案 0 :(得分:3)

我认为您的案例中的解决方案是提到的 AggregateResourceBundleLocator 。但是,属性文件的名称不能相同。内部 ResourceBundle#getBundle 被调用,它返回一个 ResourceBundle 。没有组合/合并具有相同名称的属性文件的概念。

编辑1

关于标准的做法 - 遗憾的是没有。 Bean Validation 1.1(hibernate.onjira.com/browse/BVAL-252)存在一个未解决的问题,以解决提供约束库的问题,但目前还没有任何决定,消息插值也需要解决。也许你对它应该如何运作有所了解。如果是,请向专家组提出您的建议。检查beanvalidation.org

答案 1 :(得分:2)

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;
}