ValidationMessages.properties文件之间的冲突

我用来收集公共库中的所有validation约束。 在jar的根目录中,我放了一个ValidationMessages_it.properties文件。 一切正常,如果我将这个库放入jsf 2 war项目中,所有validation消息都会正确显示。 但是,如果我在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 = "[az]", 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[] payload() default {}; } 

PS: 请注意,消息键位于@Pattern注释而不是message(),这似乎是一个错误,但否则它永远不会起作用!

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

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

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

编辑2

为了更好地理解Hardy的答案,我打开了另一个问题来validation我的假设是否正确: 共享库中的Bean Validation约束

编辑3

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

  • 可以部署在符合java EE 6的应用程序服务器中的war工件
  • 包含两个maven项目的源zip,一个用于库,一个用于webapp

我测试了Glassfish 3.1.2,JBoss AS 7.1.1,Geronimo 3.0.0中的webapp

Glassfish和Jboss具有相同的行为。 在Geronimo中,它的工作效果更好一些。

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

编辑1

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

2015年7月发布的Hibernate Validator 5.2增加了对从不同JAR文件聚合具有相同名称的所有资源包的支持。 默认情况下禁用此function,可以在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; }