问题
I use to collect all my validation constraints in a common library. In the root of the jar I put a ValidationMessages_it.properties
file.
All works fine, if I put this library into a jsf 2 war project all validation messages are shown correctly.
However a problem arise if I put another ValidationMessages_it.properties
in the war artifact too. In this case a {library.message_key} string is shown.
I think Bean Validation find the right property file in the war and does not take into account that in the library. How can I solve?
EDIT
Try to clarify my configuration:
I have a library, commons.jar, that contains custom constraints. In order to set messages for these constraints I've added a ValidationMessages_it.properties in the root of this library
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: note that the message key is on the @Pattern annotation instead of message(), this could seem a mistake but otherwise it never works!
After that I want to use this commons.jar in my web app project (jsf/mojarra 2.1). All works fine. The displayed error message is Questo è l'errore di cui parlavo
But now suppose I define new validation constraints in my webapp, so I want to supply translations for these constraints by adding a ValidationMessages_it.properties in WEB-INF/classes folder. In this case the displayed error message is {library.custom}
So I think that BV (or jsf?) find the bundle in the war and does not take into account that in the commons.jar. It does not find the key library.custom in the ValidationMessages_it.properties that resides in the WEB-INF/classes folder thus return {library.custom} literally.
EDIT 2
In order to better understand the Hardy's answer I have opened another question to verify if my assumptions are right: Bean Validation constraints in a shared library
EDIT 3
Based on aforementioned question my package structure seems correct. I uploaded a simple web app to show the problem:
- a war artifact that can be deployed in a java EE 6 compliant application server
- a source zip that contains two maven projects, one for library and one for webapp
I tested the webapp in Glassfish 3.1.2, JBoss AS 7.1.1, Geronimo 3.0.0
Glassfish and Jboss have the same behavior. In Geronimo it works a little bit better.
回答1:
I think the solution in your case is the mentioned AggregateResourceBundleLocator. However, you cannot have the same name for the property files. Internally ResourceBundle#getBundle is called which does return a single ResourceBundle. There is no concept of combining/merging properties files with the same name.
EDIT 1
Regarding a standard way of doing it - unfortunately there is none. There is an open issue for Bean Validation 1.1 (hibernate.onjira.com/browse/BVAL-252) to address the ability to provide constraint libraries, but there is nothing decided yet and the message interpolation would needs addressing as well. Maybe you have an idea on how it should work. If so provide your suggestion to the expert group. Check beanvalidation.org
回答2:
Hibernate Validator 5.2, released in July 2015, added support for aggregating all resource bundles with the same name from different JAR files. This functionality is disabled by default, and can be configured in org.hibernate.validator.resourceloading.PlatformResourceBundleLocator.
Example:
PlatformResourceBundleLocator resourceBundleLocator =
new PlatformResourceBundleLocator(ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, null, true);
Validator validator = Validation.byProvider(HibernateValidator)
.configure()
.messageInterpolator(new ResourceBundleMessageInterpolator(resourceBundleLocator))
.buildValidatorFactory()
.getValidator();
Equivalent code for a Spring project using Java config:
@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;
}
来源:https://stackoverflow.com/questions/11599208/conflict-between-validationmessages-properties-files