Reputation: 135
Firstly, I am newbie in Vaadin 7. I was just trying out some vaadin demo when I discovered the BeanFieldGroup.class. As I saw ,this class bound a field to a bean property. In the bean the properties are annotated with validation constraints annotations ( JSR 303 ). In this case my pom.xml include hibernate validator dependency:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.CR1</version>
</dependency>
I made ValidationMessage.properties file and put there some messages, ( with Hungarian characters ) and it has been saved UTF-8 format,for example :
validation.NotBlank=Árvíztűrő tükörfúrgép
And here is the annotated bean property:
@NotNull(message = "{validation.NotBlank}")
private String name = null;
I can see, when I change the field value to null, Vaadin show me my previous constraint error message, but with wrong character coding.
In other hand - without Vaadin, but Spring,I can use the next simple formula where the character coding is appropriate me ( as you can see I use Spring ReloadableResourceBundleMessageSource) :
private MessageSource MessageSource(){
ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
reloadableResourceBundleMessageSource.setCacheSeconds(5000);
reloadableResourceBundleMessageSource.setFallbackToSystemLocale(false);
reloadableResourceBundleMessageSource.setDefaultEncoding("UTF-8");
Properties properties = new Properties();
properties.setProperty("fileEncodings", "UTF-8");
reloadableResourceBundleMessageSource.setFileEncodings(properties);
reloadableResourceBundleMessageSource.setBasename("classpath:/locales/messages");
return reloadableResourceBundleMessageSource;
}
@Bean
public LocalValidatorFactoryBean validator(){
LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
factory.setValidationMessageSource(MessageSource());
return factory;
}
My question is: Can Somebody tell me the right solution how do I configure hibernate validator or Vaadin to read property files with UTF-8 encoding ?
Upvotes: 0
Views: 1688
Reputation: 7098
Vaadin's BeanFieldGroup
uses another Vaadin class BeanValidator
for JSR-303 validation. If you take a look at it's source code at BeanValidator.getJavaxBeanValidator()
and getJavaxBeanValidatorFactory()
methods, wou will see that it's building it's own Validator
and ValidatorFactory
instances. You'll need to subclass it and override the getJavaxBeanValidatorFactory()
method with one that uses a ValidatorFactory
obtained from your Spring context, which is properly set up to use Spring's own UTF-8 encoded MessageSource
as you already configured it in your example. It will also help you with debugging as Spring's MessageSource
can be reloadable, which is a huge saver.
EDIT: following a question in comments on how to override with subclassing I realized that with the current state of this part of the Vaadin API as of version 7.5.9, I can't do it elegantly. Since we can't do it elegantly we could do it the quick and dirty way by reflection with this hack implemented as a spring component:
@Component
public class VaadinValidationHack implements InitializingBean {
@Autowired
private ValidatorFactory validatorFactory;
protected void hack() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field field = BeanValidator.class.getDeclaredField("factory");
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(null, validatorFactory);
}
@Override
public void afterPropertiesSet() throws Exception {
hack();
}
}
Upvotes: 1
Reputation: 18980
By default, ISO-8859-1 encoding is used when reading properties files. Characters not available in that encoding must be converted using Unicode escapes ("\u1234"), e.g. using the native2ascii tool. See this answer to a related question for some more details.
Alternatively, you could plug in a custom ResourceBundleLocator
which reads properties using UTF-8 encoding. The Hibernate Validator reference guide describes how to do this. As a starting point, you could take PlatformResourceBundleLocator and adapt it as per your requirements.
Upvotes: 2