Spring 4 & Hibernate 5 验证程序 messageSource 不工作
Spring 4 & Hibernate 5 validator messageSource does not work
我无法使用休眠验证 5.1.0.Final 和 Spring MVC 4.2.5.RELEASE.
我的网络配置:
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
@Bean
@Autowired
public MethodValidationPostProcessor getValidationPostProcessor(LocalValidatorFactoryBean validator) {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setValidator(validator);
return processor;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
@Override
public Validator getValidator() {
return validator();
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor l = new LocaleChangeInterceptor();
l.setParamName("lang");
return l;
}
@Bean
public SessionLocaleResolver localeResolver(){
SessionLocaleResolver s = new SessionLocaleResolver();
s.setDefaultLocale(Locale.ENGLISH);
return s;
}
我有一个 ExceptionHanlder,它获取验证消息并将其作为 json:
推回
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ValidationError handleConstraintViolation(final ConstraintViolationException exception) {
ValidationError v = new ValidationError();
exception.getConstraintViolations().forEach(violation -> {
v.addError(violation.getPropertyPath().toString(), violation.getMessage());
});
logger.warn(exception, exception);
return v;
}
我在 src/main/resources/i18n/ 中有 3 个文件:messages_en_EN.properties、messages_pl_PL.properties、messages.properties。
我的经过验证的模型 class 有一个经过验证的参数:
@Column(name = "VALUE_", nullable = false)
@Email(message = "{Email.contractorContactEmail.value}")
@NotNull(message = "{NotNull.contractorContactEmail.value}")
private String value;
我看到的是休眠验证器查看 classpath:ValidationMessages 属性而不是我的 spring 消息源。这对我来说可能没问题,但 Hibernate 不想翻译这些消息 - 区域设置始终是服务器默认设置。我究竟做错了什么??我该如何解决?
PS。在控制器中我使用@org.springframework.validation.annotation.Validated.
PS2。我确定我的 messageSource 工作正常,因为如果我将这段代码添加到 ExceptionHandler 中,它会完美地翻译,但我知道这是不好的做法。
exception.getConstraintViolations().forEach(violation -> {
String messageTemplate = violation.getMessageTemplate();
if (messageTemplate.startsWith("{") && messageTemplate.endsWith("}")) {
String key = StringUtils.substring(messageTemplate, 1, messageTemplate.length() - 1);
v.addError(violation.getPropertyPath().toString(), messageSource.getMessage(key, null, LocaleContextHolder.getLocale()));
}
});
我可以马上告诉你的是,从你的配置来看,你的消息在错误的地方 - 你配置消息源查看 i18/messages
但你的消息在 class路径根。因此,您的消息源定义应如下所示:
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
除此之外,其余配置看起来还不错。我猜你正在使用 WebMvcConfigurerAdapter
class?
编辑:
对于未来 reader 的参考,问题与配置无关,JPA 实体在 @OneToMany
字段上缺少 @Valid
注释,因此控制器级别的验证无法识别它,Hibernate 的JPA 验证器使用默认消息。
我无法使用休眠验证 5.1.0.Final 和 Spring MVC 4.2.5.RELEASE.
我的网络配置:
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
@Bean
@Autowired
public MethodValidationPostProcessor getValidationPostProcessor(LocalValidatorFactoryBean validator) {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setValidator(validator);
return processor;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
@Override
public Validator getValidator() {
return validator();
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor l = new LocaleChangeInterceptor();
l.setParamName("lang");
return l;
}
@Bean
public SessionLocaleResolver localeResolver(){
SessionLocaleResolver s = new SessionLocaleResolver();
s.setDefaultLocale(Locale.ENGLISH);
return s;
}
我有一个 ExceptionHanlder,它获取验证消息并将其作为 json:
推回 @ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ValidationError handleConstraintViolation(final ConstraintViolationException exception) {
ValidationError v = new ValidationError();
exception.getConstraintViolations().forEach(violation -> {
v.addError(violation.getPropertyPath().toString(), violation.getMessage());
});
logger.warn(exception, exception);
return v;
}
我在 src/main/resources/i18n/ 中有 3 个文件:messages_en_EN.properties、messages_pl_PL.properties、messages.properties。 我的经过验证的模型 class 有一个经过验证的参数:
@Column(name = "VALUE_", nullable = false)
@Email(message = "{Email.contractorContactEmail.value}")
@NotNull(message = "{NotNull.contractorContactEmail.value}")
private String value;
我看到的是休眠验证器查看 classpath:ValidationMessages 属性而不是我的 spring 消息源。这对我来说可能没问题,但 Hibernate 不想翻译这些消息 - 区域设置始终是服务器默认设置。我究竟做错了什么??我该如何解决?
PS。在控制器中我使用@org.springframework.validation.annotation.Validated.
PS2。我确定我的 messageSource 工作正常,因为如果我将这段代码添加到 ExceptionHandler 中,它会完美地翻译,但我知道这是不好的做法。
exception.getConstraintViolations().forEach(violation -> {
String messageTemplate = violation.getMessageTemplate();
if (messageTemplate.startsWith("{") && messageTemplate.endsWith("}")) {
String key = StringUtils.substring(messageTemplate, 1, messageTemplate.length() - 1);
v.addError(violation.getPropertyPath().toString(), messageSource.getMessage(key, null, LocaleContextHolder.getLocale()));
}
});
我可以马上告诉你的是,从你的配置来看,你的消息在错误的地方 - 你配置消息源查看 i18/messages
但你的消息在 class路径根。因此,您的消息源定义应如下所示:
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
除此之外,其余配置看起来还不错。我猜你正在使用 WebMvcConfigurerAdapter
class?
编辑:
对于未来 reader 的参考,问题与配置无关,JPA 实体在 @OneToMany
字段上缺少 @Valid
注释,因此控制器级别的验证无法识别它,Hibernate 的JPA 验证器使用默认消息。