Spring Boot验证消息未解析

Kor*_*hen 17 java spring thymeleaf spring-boot

我无法解析验证消息.

我一直在搜索和阅读网络和SO几个小时,我想将问题与自定义弹簧验证错误的明确答案联系起来

我确实有一个MessageSourcebean定义并且messages.properties正确读取,因为我也使用它来显示常规文本th:text="#{some.prop.name},这确实很好用.只是验证错误不会以它应该的方式工作.我确定这是一个我忽略的愚蠢错误......验证本身工作正常.

约束:

@NotEmpty(message="{validation.mail.notEmpty}")
@Email()
private String mail;
Run Code Online (Sandbox Code Playgroud)

messages.properties:

# Validation
validation.mail.notEmpty=The mail must not be empty!
Run Code Online (Sandbox Code Playgroud)

模板部分:

<span th:if="${#fields.hasErrors('mail')}" th:errors="*{mail}"></span>
Run Code Online (Sandbox Code Playgroud)

显示的文字:

{validation.mail.notEmpty}
Run Code Online (Sandbox Code Playgroud)

我尝试了很多变化,都没有成功.

@NotEmpty(message="validation.mail.notEmpty")
@NotEmpty(message="#{validation.mail.notEmpty}")
Run Code Online (Sandbox Code Playgroud)

只显示消息字符串的确切值,无需解析.

<span th:if="${#fields.hasErrors('mail')}" th:errors="${mail}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{mail}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{*{mail}}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{__*{mail}__}"></span>
Run Code Online (Sandbox Code Playgroud)

会导致错误.


编辑:

经过调试,我偶然发现了这个问题:

类: org.springframework.context.support.MessageSourceSupport

方法: formatMessage(String msg, Object[] args, Locale locale)

将被召唤

formatMessage("{validation.mail.notEmpty}", null, locale /*German Locale*/)

它会遇到 if (messageFormat == INVALID_MESSAGE_FORMAT) {

所以...我的消息格式不正确.这超出了我的范围/知识.谁知道这意味着什么?

Szy*_*iak 45

LocalValidatorFactoryBean您的应用程序配置中似乎缺少定义.下面你可以找到的一个实例Application类,它定义两个bean:LocalValidatorFactoryBeanMessageSource使用messages.properties文件.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@SpringBootApplication
public class Application {

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

说完LocalValidatorFactoryBean豆定义您可以使用自定义的验证信息,如:

@NotEmpty(message = "{validation.mail.notEmpty}")
@Email
private String email;
Run Code Online (Sandbox Code Playgroud)

messages.properties:

validation.mail.notEmpty=E-mail cannot be empty!
Run Code Online (Sandbox Code Playgroud)

和Thymeleaf模板文件:

<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Name Error</p>
Run Code Online (Sandbox Code Playgroud)

样品申请

https://github.com/wololock/stackoverflow-answers/tree/master/45692179

我准备了示例Spring Boot应用程序来反映您的问题.随意克隆它并在本地运行它.如果值贴有形式不符合它会显示翻译验证消息@NotEmpty@Email验证.

WebMvcConfigurerAdapter 组态

在扩展的情况下,WebMvcConfigurerAdapter您必须通过覆盖getValidator()父类的方法来提供验证器,例如:

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    @Override
    public Validator getValidator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

    // other methods...
}
Run Code Online (Sandbox Code Playgroud)

否则,如果您LocalValidatorFactoryBean在其他位置定义bean,它将被覆盖并且不会产生任何影响.

我希望它有所帮助.


wan*_*arn 16

不确定您使用的是哪个版本的弹簧靴.我正在使用Spring启动2.0.1.RELEASE.更清晰的解决方案是将所有验证消息移至ValidationMessages.properties.这样您就不必覆盖自动配置Validator()并设置MessageSource.

  • 文件ValidationMessages.properties应该直接放置在“ resources”目录中,而不是在子目录中,否则它将不起作用 (2认同)

Ram*_*ngh 5

我使用的是 Spring boot 2.2.7 版本,只需将属性文件名更改为 ValidationMessages.properties,无需其他配置即可工作。