【问题标题】:spring-mvc @Size annotation does not resolve error message correctlyspring-mvc @Size 注解不能正确解析错误信息
【发布时间】:2015-09-08 05:58:47
【问题描述】:

我正在尝试使用 Spring 中的 Validator 和 ValidationMessages.properties 来定义 javax 注释中定义的错误消息(@NotNull@Size 等)。但是,打印的是原始字符串(如“Size.firstName.length”)而不是已解析的消息。此外,tomcat 显示一个警告,上面写着

WARNING: ResourceBundle [/WEB-INF/messages/] not found for MessageSource: Can't find bundle for base name /WEB-INF/messages/, locale en_US

此外,我还在这里检查了类似的问题,但没有任何效果。假设这是一个简单的 Person POJO。

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

    @NotNull
    @Size(min = 2, max = 10, message = "Size.firstName.length")
    private String firstName;

    @NotNull
    @Size(min = 2, max = 10)
    private String lastName;

    public User() {};

    public User(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

...
}

相关配置相关jsp文件如下,

WebConfig.java

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"spittr.web", "spittr.data"})
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("/WEB-INF/messages/");
        return messageSource;
    }

    @Bean
    public LocalValidatorFactoryBean validatorFactory() {
        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
        factoryBean.setValidationMessageSource(messageSource());
        return factoryBean;
    }

    @Override
    public Validator getValidator() {
        return validatorFactory();
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

registerForm.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<%@ page session="false" %>

<html>
    <head>
        <title>Spittr</title>
        <link href="<c:url value="/resources/css/user.css" />" rel="stylesheet">
    </head>
    <body>
        <h1>Register</h1>
        <sf:form method="POST" commandName="user">
            First Name: <sf:input path="firstName"/>
                        <sf:errors path="firstName" cssClass="error"/><br/>
            Last Name: <sf:input path="lastName"/>
                       <sf:errors path="lastName" cssClass="error"/><br/>
            <input type="submit" value="Register">
        </sf:form>
    </body>
</html>

ValidationMessages.properties

firstName.size=First Name must be between {min} and {max} charatecters long.

而ValidationMessages.properties在

- webapp
  - WEB-INF
    - messages
      - ValidationMessages.properties

所以,正如我所说,如果 firstName 无效,则不会呈现错误消息并显示“Size.firstName.length”的原始字符串。

【问题讨论】:

  • 包括 {} 大括号围绕您的消息 @Size(min = 2, max = 10, message = "{Size.firstName.length}")
  • 谢谢,但这也不起作用。我之前试过
  • 您想要特定区域的消息吗?
  • 这是我解决默认属性后的第二步。问题是我遵循了每种类型的配置,但没有任何效果。
  • A ResourceBundle 由类加载器加载。 WEB-INF 不是类路径的一部分。你的属性文件应该在WEB-INF/classes 下。假设它在WEB-INF/classes/foo/bar/messages/ValidationMessages.properties,它的基本名称是foo.bar.messages.ValidationMessages

标签: java spring jsp spring-mvc bean-validation


【解决方案1】:

Spring 将消息查找委托给配置的MessageSource,它不为此使用ValidationMessages.properties。 (这就是默认 bean 验证所做的!)。

但是您的MessageSource 的配置是错误的。 baseName 应该是文件名而不是目录。接下来您将使用ResourceBundleMessageSource,它只能从classpath 加载文件。重新配置您的MessageSource

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("messages");
    return messageSource;
}

现在将您的 ValidationMessages.properties 重命名为 messages.properties 并将其放入 src\main\resources\

【讨论】:

  • 啊终于。这行得通。非常感谢。但是我正在阅读的资源都使用 ValidationMessages.properties 没有初始化任何 MessageSource 但不知道为什么我的不工作。书上说如果我想使用内化,我需要创建ValidationMessages_es.properties。那么,如果我只给出名称而不是目录名称,我该如何实现这种内化呢?
  • 正如我在 cmets 中提到的,这是默认的 Bean 验证。当使用 Spring 引导验证并且您配置了 MessageSource 将被使用而不是默认值时。如果您不希望这样,请不要配置MessageSource,默认值将适用。
  • 现在我明白了。我也实现了使用默认值。非常感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
  • 2018-03-28
  • 1970-01-01
  • 2018-05-22
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多