【问题标题】:Spring 4 & Hibernate 5 validator messageSource does not workSpring 4 和 Hibernate 5 验证器消息源不起作用
【发布时间】:2016-12-06 06:25:37
【问题描述】:

我无法使用 Spring MVC 4.2.5.RELEASE 进行休眠验证 5.1.0.Final。

我的网络配置:

    @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。 我的带有验证的模型类有一个经过验证的参数:

    @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()));
            }
});

【问题讨论】:

    标签: spring hibernate spring-mvc hibernate-validator


    【解决方案1】:

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

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

    除此之外,其余配置看起来还不错。我猜你正在使用WebMvcConfigurerAdapter 类?

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

    【讨论】:

    • 操作对不起我的错误。我的消息在 src/main/resources/i18n 中。
    • 我正在与它战斗 3 天,但无法配置它...我在想是否可能是 spring 4 和休眠验证器 5 之间的集成问题?我正在使用 jboss 作为 Web 应用程序服务器。也许它可能会有所帮助?也许我错过了一些罐子?我不知道..
    • 不,如果您的消息配置正确,那么我猜 MVC 没有正确选择 LocalValidatorFactoryBean。您可以尝试将@Autowired private LocalValidatorFactoryBean validator; 字段添加到您的配置类中并从getValidator() 返回字段值吗?
    • 是的,我正在使用 WebMvcConfigurerAdapter 类。是的,我尝试在 ExceptionHandling 类中自动装配 LocalValidatorFactoryBean ,它从配置中返回 bean。区域设置也可以工作,因为 LocaleContextHolder.getLocale() 返回正确的值。
    • 你知道我可以调试休眠以查看可能是什么问题的任何入口点吗?
    猜你喜欢
    • 1970-01-01
    • 2016-10-09
    • 2019-04-21
    • 2018-04-10
    • 2013-08-12
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多