Spring MVC表单验证消息未加载

时间:2013-08-20 15:50:52

标签: java spring validation spring-mvc

我正在尝试在资源文件中定义错误消息,但我似乎无法加载它们,所以我可以在我的控制器中使用它们。

我的 servlet-context.xml 文件:

<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <beans:property name="basename" value="classpath:messages" />
</beans:bean>

我的表单

public class LoginForm {
    @NotEmpty
    private String username;
    // getters and setters
}

我的 messages.properties 文件(在我的源文件夹的根目录中,因此它被编译到我的classes文件夹的根目录中):

NotEmpty.loginForm.username=test1
NotEmpty.username=test2
NotEmpty.java.lang.String=test3
NotEmpty=test4

我的控制器

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(@Valid LoginForm form, BindingResult result) {
    if (result.getFieldErrors().size() > 0) {
        FieldError firstError = result.getFieldErrors().get(0);
        System.out.println(firstError.getDefaultMessage());
    }
    // ...
}

但是,getDefaultMessage调用的输出永远不会在我的资源文件中定义!始终为may not be empty(默认值)。

我在我的上下文文件中尝试了各种不同的条目,但似乎它没有加载资源文件。我做错了什么?

4 个答案:

答案 0 :(得分:1)

根据这个documentation,您只需要在项目类路径的根目录下放置一个名为ValidationMessages.properties的属性文件。

然后,您可以使用以下格式添加属性

org.hibernate.validator.constraints.NotEmpty.message=Default message, can not be empty 
NotEmpty.ClassName.fieldName=fieldName can not be empty.

其中ClassName是您班级的名称,fieldName是该班级字段的名称。

您可能需要进行一些配置才能设置正确的MessageInterpolator,但我认为默认配置可以满足您的需求。

答案 1 :(得分:0)

第一个想法:

尝试将属性键从NotEmpty.loginForm.username重命名为NotEmpty(只是为了检查messageSource是否正常工作)。如果还没有工作那么

第二个想法:

您在哪里执行组件扫描? 假设您有两个spring配置:applicationContext.xml(或其他名称)和servlet-context.xml。

如果你在applicationContext中有这样的结构<context:component-scan base-package="by.company.app" />,那么你的控制器没有定义的messageSource - 所以它无法加载自定义的消息。这是因为@Controller bean在一个spring上下文中,MessageSource bean在另一个中。 (要检查这一点,您可以在控制器中简单地声明@Autowired MessageSource messageSource字段,并在调试中看到它是否为空)在这种情况下,您可以将applicationContext中的组件扫描修改为:

<context:component-scan base-package="by.company.app">
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

并将以下配置添加到servlet-context.xml:

<context:component-scan base-package="by" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

希望这有帮助

答案 2 :(得分:0)

不幸的是,它似乎必须定义MessageSource,然后在适当的Java类中使用。 getDefaultMessage()方法似乎无法从邮件属性中读取。

在组件扫描类中:

@Autowired
private MessageSource messageSource;
public String getMessage(FieldError field) {
    return messageSource.getMessage(field, null);
}

这将迭代消息属性文件中的所有可能性,然后 - 如果未找到任何内容 - 则返回getDefaultMessage()结果。

此外,我更新了我的servlet-context.xml文件,以定义我的messageSource,其基本名称值为/WEB-INF/classes/messages,而不是我在上面的问题中所拥有的。

答案 3 :(得分:0)

我花了一些时间来解决这个问题,我做了以下更改,现在它在Spring 4.0 MVC和Hibernate 4.1.9中运行良好

1.在源文件夹下输出消息。

  1. 如果ReloadableResourceBundleMessageSource无效,则更改为

          类= “org.springframework.context.support.ResourceBundleMessageSource” &GT;

  2. 更改属性,例如'&lt;'属性名称=“basename”value =“messages”/&gt;

  3. 在Message.properties文件中,密钥应采用以下格式。

    NotEmpty.userForm.userId

    userForm-->Model class name.
    
  4. (如果你的Model类名是UserForm,那么它应该是                                      被称为userForm)

        userId--> attribute of userForm class