春天4& Hibernate 5验证器messageSource不起作用

时间:2016-08-01 08:36:27

标签: spring hibernate spring-mvc hibernate-validator

我无法使用Spring MVC 4.2.5.RELEASE来使用hibernate验证5.1.0.Final。

我的WebConfig:

    @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 /:messages_en_EN.properties,messages_pl_PL.properties,messages.properties中有3个文件。 我的带验证的模型类有一个经过验证的参数:

    @Column(name = "VALUE_", nullable = false)
    @Email(message = "{Email.contractorContactEmail.value}")
    @NotNull(message = "{NotNull.contractorContactEmail.value}")
    private String value;

我看到的是,hibernate验证器会查看类路径: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()));
            }
});

1 个答案:

答案 0 :(得分:0)

我可以立即告诉您,从您的配置判断,您的消息位于错误的位置 - 您已将消息源配置为查看i18/messages,但您的消息位于类路径根目录中。因此,您的消息源定义应如下所示:

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("messages");
    messageSource.setDefaultEncoding("UTF-8");
    messageSource.setUseCodeAsDefaultMessage(true);
    return messageSource;
}

除此之外,配置的其余部分看起来非常好。我猜你正在使用WebMvcConfigurerAdapter类?

修改 对于未来读者的参考,该问题与配置无关,JPA实体在@Valid字段上缺少@OneToMany注释,因此控制器级验证无法获取它并且Hibernate的JPA验证器使用默认消息。