我有一个使用 JPA、Hibernate 等的 Spring Boot 2.4.2 REST 应用程序。到目前为止,我使用一个MessageSource
用于应用程序错误(位于 i18n/messages 中)和ValidationMessages
bean 验证的默认值。
这是我的配置的一部分:
public static Set<Locale> LOCALES = Set.of(new Locale("en"), new Locale("it"));
@Bean
public LocaleResolver localeResolver() {
SmartLocaleResolver localeResolver = new SmartLocaleResolver();
return localeResolver;
}
public class SmartLocaleResolver extends AcceptHeaderLocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
if (StringUtils.isBlank(request.getHeader("Accept-Language"))) {
return Locale.getDefault();
}
List<Locale.LanguageRange> list = Locale.LanguageRange.parse(request.getHeader("Accept-Language"));
Locale locale = Locale.lookup(list, LOCALES);
return locale;
}
}
@Primary
@Bean("messageSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setAlwaysUseMessageFormat(true);
messageSource.setBasenames("classpath:/i18n/messages");
// set to true only for debugging
messageSource.setUseCodeAsDefaultMessage(false);
messageSource.setFallbackToSystemLocale(false);
return messageSource;
}
到目前为止,我的应用程序支持 2 种语言:it和en。现在的问题是应用程序的消息在代理的语言(浏览器)中正确本地化,但验证错误不是。
我发现 Hibernate 使用默认语言环境 (Locale.getDefault()) 并自定义行为我应该自定义语言环境分辨率。
所以我尝试创建一个自定义 hibernateValidator(我在我的 entityFactory 中设置):
@Bean
public MessageSource validationMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setAlwaysUseMessageFormat(true);
messageSource.setBasenames("classpath:/ValidationMessages");
// set to true only for debugging
messageSource.setUseCodeAsDefaultMessage(false);
messageSource.setFallbackToSystemLocale(false);
return messageSource;
}
@Bean("hibernateValidator")
public LocalValidatorFactoryBean hibernateValidator() {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
factoryBean.setValidationMessageSource(validationMessageSource());
return factoryBean;
}
和解析器:
public class HibernateLocaleResolver implements LocaleResolver {
@Override
public Locale resolve(LocaleResolverContext context) {
return LocaleContextHolder.getLocale();
}
}
这样做,语言环境解析工作正常,但参数替换不行。我的意思是这样的消息:
server.validators.ArraySize.message = The number of values must be between [{min}] and [{max}].
我有一个例外:
"exception": "java.lang.IllegalArgumentException", "message": "can't parse argument number: min"
所以我更改了上面的配置,添加了 MessageInterpolator:
factoryBean.setMessageInterpolator(new ResourceBundleMessageInterpolator(LOCALES, Locale.ENGLISH, new HibernateLocaleResolver(), false));
此时参数已正确解析,但语言环境解析再次不起作用。
您能否指出我正确的方向,试图解释 Spring Boot - Hibernate Validator 组合遵循的最佳实践?