如何在 Spring 中使用从属性文件获取的错误消息的注释验证?
Posted
技术标签:
【中文标题】如何在 Spring 中使用从属性文件获取的错误消息的注释验证?【英文标题】:How to use annotation validation in Spring with error message gotten from properties file? 【发布时间】:2011-08-12 19:06:16 【问题描述】:我是春季新手。
我在我的域类中设置了这样的验证:
public class Worker
@NotNull(message="Name must be input")
@Size(min=1,max=50, message="Name must not exceed 50 characters")
private String name;
...
这是jsp文件:
<form:input path="code" readonly="false" />
<font color="red"><form:errors path="code" />
以及控制器代码:
@RequestMapping(value="/test",method=RequestMethod.POST)
public void form(@Valid Worker worker, BindingResult result)
if (result.hasErrors())
return;
...
它有效,但是如何在我的消息源中用一些文本(如 worker.name.overflow)替换“名称不得超过 50 个字符”?是否需要在 BindingResult 中添加 messageResolver?
所有搜索结果似乎都在说要编写自定义验证器类,但我现在想使用注释。我很确定有办法,因为在this question 有人已经做到了。
【问题讨论】:
【参考方案1】:要告诉 Hibernate 验证器对代码进行查找,请将 message 的值放在大括号中,例如 @NotNull(message="worker.name.NotNull"
,然后将翻译放在类路径根目录下的 ValidationMessages.properties (/WEB-INF/classes , Maven 中的资源文件夹等)。
验证器实现独立地查找它们,然后它们继续 BindingResult 已经被翻译为默认消息。发生在 Spring 消息源之外。理论上,您可以覆盖 LocalValidatorFactory bean,将验证器的消息输出作为代码放到 Errors 对象上,然后在注释中去掉大括号,以便 Hibernate Validator 将其传递。将 JSR-303 ConstraintViolations 转换为 Spring Errors 的源代码非常简单,易于阅读和扩展。它只是将注解的名称作为代码,将注解属性作为 args,然后将验证器的翻译作为默认消息。你可以阅读实现here。
您可以将javax.validation.MessageInterpolator
添加到您的javax.validation.Configuration
以告诉它在其他属性文件中查找消息。如果您使用的是 Spring LocalValidatorFactory bean,它上面有一个 setMessageInterpolator()
,您可以使用它来注入一个。检查 this 源以获取 Hiberate 提供程序实现。
【讨论】:
我已经像你的第一段那样做了:在WEB-INF中放一个文件名ValidationMessages.properties,并为消息添加大括号,但它没有改变。似乎找不到 ValidationMessages.properties。 抱歉我的错误,我错过了将 ValidationMessages.properties 放在类路径中的部分。如果您能告诉我如何修改此默认位置,我将不胜感激? 您可以更具体地更改属性文件位置吗?我正在使用弹簧,但你的解释对我来说听起来像是希腊语! localValidatorFactoryBean.setMessageInterpolator(new ResourceBundleMessageInterpolator(new AggregateResourceBundleLocator(Arrays.asList("my.package.MyFileName", "my.other.package.AnotherFileName"))));LocalValidatorFactoryBean
有一个validationMessageSource
属性,您可以在该属性上设置一个Spring MessageSource
,这比设置您自己的MessageInterpolator
更容易。【参考方案2】:
这是对问题的一点解释。
@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) = validation annotation name
loginForm = My Class Name
loginId = Property name in LoginForm class.
【讨论】:
以上是关于如何在 Spring 中使用从属性文件获取的错误消息的注释验证?的主要内容,如果未能解决你的问题,请参考以下文章
SpringMVC利用Spring自带验证框架验证获取错误信息出现乱码问题
[坑]Spring利用注解@Value获取properties属性为null
如何从 Spring Boot Config Server 提供的其他属性文件中的 application.properties 获取密钥?