在Spring中没有从消息属性文件中获取验证消息

时间:2012-07-24 21:51:12

标签: spring bundle message bean-validation

我昨天工作了,然后我做了一些事情,现在我一直在尝试修复它几个小时,我再也无法让它继续工作了。

我有一个包含<form:form>的Spring MVC应用程序,当用户键入错误信息时,我想从.properties文件中显示自定义错误消息(<form:errors>)。 JSR-303注释中定义了什么“错误”。

摘自表格:

<form:form method="post" action="adduserprofile" modelAttribute="bindableUserProfile">
<table>
    <tr>
        <td><form:label path="firstName">Voornaam</form:label></td>
        <td>
            <form:input path="firstName"/>
            <form:errors path="firstName" />
        </td>
    </tr>
    <tr>
        <td><form:label path="lastName">Achternaam</form:label></td>
        <td>
            <form:input path="lastName"/>
            <form:errors path="lastName" />
        </td>
    </tr>

摘自BindableUserProfile:

   @NotNull
@Size(min = 3, max = 40, message="{errors.requiredfield}")
public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

@NotNull
@Size(min = 3, max = 40,  message="errors.requiredfield")
public String getLastName() {
    return lastName;
}

摘录自控制器:

    @RequestMapping(value = "/edit/{userProfileId}", method = RequestMethod.GET)
public String createOrUpdate(@PathVariable Long userProfileId, Model model) {
    if (model.containsAttribute("bindableUserProfile")) {
        model.addAttribute("userProfile", model.asMap().get("bindableUserProfile"));
    } else {
        UserProfile profile = userProfileService.findById(userProfileId);
        if (profile != null) {
            model.addAttribute(new BindableUserProfile(profile));
        } else {
            model.addAttribute(new BindableUserProfile());
        }
    }

    model.addAttribute("includeFile", "forms/userprofileform.jsp");
    return "main";
}

@RequestMapping(value = "/adduserprofile", method = RequestMethod.POST)
public String addUserProfile(@Valid BindableUserProfile userProfile, BindingResult result, Model model) {
    if (result.hasErrors()) {
        return createOrUpdate(null, model);
    }

    UserProfile profile = userProfile.asUserProfile();
    userProfileService.addUserProfile(profile);
    return "redirect:/userprofile";
}

摘自application-context.xml

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

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource">
        <ref bean="messageSource"/>
    </property>
</bean>

在资源/消息中,我有两个文件,messages_en.properties和messages_nl.properties。两者都有相同的简单内容:

errors.requiredfield=This field is required!!!
  • 当我提交带有空名字的表单时,我可以在控制器方法'addUserProfile()'中看到确实找到了错误。
  • 当我提交带有空名字的表单时,字段旁边会显示消息标识符,即姓氏旁边的文字文本“errors.requiredfield”或“{errors.requiredfield}”。 / LI>
  • 当我将消息属性值更改为“Foo”时,“Foo”显示为错误消息。所以错误机制本身似乎工作正常。
  • 来自application-context.xml的messageSource bean必须正确,因为它说我在更改基本名称时找不到属性文件。
  • NotNull注释未捕获空输入。 Spring将空输入视为空字符串,而不是null。

因此,似乎找到了属性文件并且正确处理了验证注释,但是Spring不明白它必须用来自属性文件的消息替换消息密钥。

2 个答案:

答案 0 :(得分:3)

Yaaaargh,我认为这从来不应该起作用。

我认为可以将JSR-303注释的“message”属性解释为一个键,以便从message.properties文件中获取关联的错误消息,但我知道我错了。

@Size(min = 3, max = 40, message="errors.requiredfield")

我的同事正在编写一个为我们创建此行为的图层,但默认情况下它不起作用。好像我有一次工作,因为我正在使用

@Size(min = 3, max = 40, message="{errors.requiredfield}")

大括号导致Spring启动查找和替换使用.properties文件作为源的过程。第二种选择仍然有用。

答案 1 :(得分:2)

过去1.5天我一直在做同样的事情,最后我找到了解决方法。

可能听起来有点疯狂,但它是一个有效的解决方案。 :)

@Size(min = 1, max = 50, message = "Email size should be between 1 and 50")

现在从验证标记中删除message = "Email size should be between 1 and 50"

执行此操作后,您的注释将如下所示。

@Size(min = 1, max = 50)

现在在控制器端调试提交表单时调用的方法。以下是我在用户点击提交时接收请求的方法。

public static ModelAndView processCustomerLoginRequest(IUserService userService, LoginForm loginForm, 
        HttpServletRequest request, HttpSession session, BindingResult result, String viewType, Map<String, LoginForm> model)

现在将调试点放在方法的第一行并调试参数“result”。

BindingResult result

在dubugging你会在代码数组中找到这样的字符串。

Size.loginForm.loginId

现在在属性文件中定义此字符串,并在该字符串中定义消息。 编译并执行。只要不验证该注释,就会显示该消息。

Size.loginForm.loginId=email shouldn't be empty.

基本上spring将自己的字符串作为其属性文件消息的键。在上面的关键:

  • Size(@Size) =验证注释名称
  • loginForm =我的班级名称
  • loginId = loginForm类中的属性名称。

这种方法的美妙之处在于它将在您使用Spring Internationalization时运行良好。它会在语言发生变化时自动切换消息文件。