首先,我是Vaadin 7的新手。当我发现BeanFieldGroup.class时,我只是尝试了一些vaadin演示。正如我所看到的,这个类将一个字段绑定到bean属性。在bean中,属性使用验证约束注释进行注释(JSR 303)。在这种情况下,我的pom.xml包含hibernate验证器依赖:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.CR1</version>
</dependency>
我制作了ValidationMessage.properties文件,并在那里放了一些消息(用匈牙利字符)并且它已经保存为UTF-8格式,例如:
validation.NotBlank=Árvíztűrő tükörfúrgép
这是带注释的bean属性:
@NotNull(message = "{validation.NotBlank}")
private String name = null;
我可以看到,当我将字段值更改为null时,Vaadin会显示我之前的约束错误消息但字符编码错误。
另一方面 - 没有Vaadin,但Spring,我可以使用下一个简单的公式,其中字符编码适合我(你可以看到我使用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;
}
我的问题是:有人可以告诉我正确的解决方案如何配置hibernate验证器或Vaadin来读取UTF-8编码的属性文件?
答案 0 :(得分:1)
默认情况下,在读取属性文件时使用ISO-8859-1编码。必须使用Unicode转义符(&#34; \ u1234&#34;)转换该编码中不可用的字符,例如使用native2ascii工具。有关更多详细信息,请参阅this answer相关问题。
或者,您可以插入使用UTF-8编码读取属性的自定义ResourceBundleLocator
。 Hibernate Validator参考指南describes如何做到这一点。作为起点,您可以选择PlatformResourceBundleLocator并根据您的要求进行调整。
答案 1 :(得分:1)
Vaadin的BeanFieldGroup
使用另一个Vaadin类BeanValidator
进行JSR-303验证。如果您使用BeanValidator.getJavaxBeanValidator()
和getJavaxBeanValidatorFactory()
方法查看它的源代码,您会发现它正在构建自己的Validator
和ValidatorFactory
个实例。您需要对其进行子类化并使用从您的Spring上下文中获取的getJavaxBeanValidatorFactory()
覆盖ValidatorFactory
方法,该方法已正确设置为使用Spring自己的UTF-8编码MessageSource
正如您在示例中已经配置的那样。它还可以帮助您进行调试,因为Spring的MessageSource
可以重新加载,这是一个巨大的救星。
编辑:关于如何覆盖子类化的评论中的问题后我意识到,从版本7.5.9开始,这部分Vaadin API的当前状态,我无法做到典雅。既然我们不能优雅地做到这一点,我们可以通过反射将快速和肮脏的方式做到这一点,将这个hack实现为弹簧组件:
@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();
}
}