Viktor Gintner
Viktor Gintner

Reputation: 135

Vaadin Bean validation with Hibernate-validator with UTF-8

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

Answers (2)

N&#225;ndor Előd Fekete
N&#225;ndor Előd Fekete

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

Gunnar
Gunnar

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

Related Questions