未解决 Spring Boot 验证消息

2022-09-01 11:10:29

我在解析验证消息时遇到问题。

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

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

约束:

@NotEmpty(message="{validation.mail.notEmpty}")
@Email()
private String mail;

messages.properties:

# Validation
validation.mail.notEmpty=The mail must not be empty!

模板部分:

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

显示的文本:

{validation.mail.notEmpty}

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

@NotEmpty(message="validation.mail.notEmpty")
@NotEmpty(message="#{validation.mail.notEmpty}")

将只显示消息字符串的确切值,不解析。

<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>

将导致错误。


编辑:

调试后,我偶然发现了这一点:

类: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) {

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


答案 1

看起来您在应用程序配置中缺少定义。您可以在下面找到定义两个bean的类示例:并使用file。LocalValidatorFactoryBeanApplicationLocalValidatorFactoryBeanMessageSourcemessages.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);
    }
}

定义Bean后,您可以使用自定义验证消息,例如:LocalValidatorFactoryBean

@NotEmpty(message = "{validation.mail.notEmpty}")
@Email
private String email;

messages.properties

validation.mail.notEmpty=E-mail cannot be empty!

和 Thymeleaf 模板文件,其中包含:

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

示例应用程序

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

我准备了反映您的问题的示例Spring Boot应用程序。随意克隆它并在本地运行它。如果与表单一起发布的值不符合和验证,它将显示已翻译的验证消息。@NotEmpty@Email

WebMvcConfigurerAdapter配置

在扩展的情况下,您必须通过重写父类的方法提供验证器,例如:WebMvcConfigurerAdaptergetValidator()

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...
}

否则,如果您在其他地方定义bean,它将被覆盖并且不会有任何影响。LocalValidatorFactoryBean

我希望它有帮助。


答案 2

不确定您使用的是哪个版本的弹簧靴。我正在使用弹簧靴。一个更明确的解决方案是将所有验证消息移动到 。这样,您就不必覆盖自动配置的并设置 .2.0.1.RELEASEValidationMessages.propertiesValidator()MessageSource


推荐