【问题标题】:Validation messages not picked up from message properties file in Spring验证消息未从 Spring 中的消息属性文件中提取
【发布时间】:2012-07-23 07:16:15
【问题描述】:

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

我有一个包含 <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}”。
  • 当我将消息属性值更改为“Foo”时,“Foo”显示为错误消息。所以错误机制本身似乎工作正常。
  • application-context.xml 中的 messageSource bean 必须正确,因为它说当我更改基本名称时它找不到属性文件。
  • NotNull 注释未捕获空输入。 Spring 将空输入视为空字符串,而不是 null。

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

【问题讨论】:

    标签: spring bundle message bean-validation


    【解决方案1】:

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

    调试时你会在codes数组中找到这样的字符串。

    Size.loginForm.loginId
    

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

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

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

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

    这种方法的美妙之处在于它在您将使用 Spring 国际化时也能正常运行。它会随着语言的变化自动切换消息文件。

    【讨论】:

      【解决方案2】:

      Yaaaargh,我认为这从一开始就不应该起作用。

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

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

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

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

      花括号导致 Spring 启动使用 .properties 文件作为源的查找和替换过程。不过,第二个选项仍然有效。

      【讨论】:

      • 你也可以从 .properties 文件中设置最小值和最大值吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2020-05-26
      • 2015-11-24
      • 2011-08-12
      • 2020-02-04
      • 2015-02-21
      相关资源
      最近更新 更多