我目前正在尝试使用 bean 验证提供自定义验证消息。
目前使用 Spring mvc 3.1.1 + apache bean 验证。
在我的豆子中,我指定:
@Size(min=1, max=50)
private String title;
在我的消息中:
Size.addForm.title=The title must not be empty and must not exceed {1} characters.
从实验中,我发现:
- {0}指"标题">
- {1}是指最大值,即 50
- {2}是指最小值,即 1
它将显示为The title must not be empty and must not exceed 50 characters.
这是正确的。
但所有这些都来自实验。我想知道是否有文档说明默认约束的参数顺序?
我尝试使用基于默认的验证消息属性的Size.addForm.title=The title must not be empty and must not exceed {max} characters.
,但最终在{max}
上出现 NumberFormatException。我认为这与插值有关?
更新
因此,这些中的每一个都独立失败,{max}
上的数字格式异常:
- messages.properties : size.addForm.title=标题不能为空,并且不能超过 {max} 个字符。
- 消息属性 : 大小=标题不能为空,并且不能超过 {max} 个字符。
- messages.properties : javax.validation.constraint.Size.message=标题不能为空,也不能超过 {max} 个字符。
- ValidationMessages.properties : Size.addForm.title=标题不能为空,并且不能超过 {max} 个字符。
- ValidationMessages.properties : size=标题不能为空,并且不能超过 {max} 个字符。
这是堆栈跟踪:
java.lang.NumberFormatException: For input string: "max"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.text.MessageFormat.makeFormat(Unknown Source)
at java.text.MessageFormat.applyPattern(Unknown Source)
at java.text.MessageFormat.<init>(Unknown Source)
at org.springframework.context.support.MessageSourceSupport.createMessageFormat(MessageSourceSupport.java:151)
at org.springframework.context.support.ResourceBundleMessageSource.getMessageFormat(ResourceBundleMessageSource.java:281)
at org.springframework.context.support.ResourceBundleMessageSource.resolveCode(ResourceBundleMessageSource.java:188)
at org.springframework.context.support.AbstractMessageSource.getMessageInternal(AbstractMessageSource.java:205)
at org.springframework.context.support.AbstractMessageSource.getMessage(AbstractMessageSource.java:146)
at org.springframework.context.support.AbstractApplicationContext.getMessage(AbstractApplicationContext.java:1214)
at org.springframework.web.servlet.support.RequestContext.getMessage(RequestContext.java:571)
at org.springframework.web.servlet.support.BindStatus.initErrorMessages(BindStatus.java:177)
at org.springframework.web.servlet.support.BindStatus.getErrorMessages(BindStatus.java:273)
at org.springframework.web.servlet.tags.form.ErrorsTag.exposeAttributes(ErrorsTag.java:173)
at org.springframework.web.servlet.tags.form.AbstractHtmlElementBodyTag.writeTagContent(AbstractHtmlElementBodyTag.java:48)
at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
这是唯一一个使用命名参数的参数,它必须是 ValidationMessages.properties,并且它必须是 jsr 303 实现默认资源包中存在的键:
- ValidationMessages.properties : javax.validation.constraint.Size.message=you know wad,大小必须介于 {min} 和 {max} 之间
基本上,当前的结论是,默认情况下,我不能对特定消息使用命名参数。命名参数仅在我覆盖默认 jsr303 资源包上的确切键时起作用 &&当我使用相同的默认 jsr303 资源包文件名(即 ValidationMessages.properties
我宁愿暂时避免使用插值,因此关于如何找出{0}或{1}或{2}的原始问题是指文档中的内容。
JSR 303 规范,4.3.1.1。"默认消息插值算法">
- 4 - 从消息字符串中提取消息参数。那些与属性名称匹配的 约束将替换为约束声明中该属性的值。
我读起来是这样的:您应该使用消息参数的注释属性的名称,而不是数字。
规范的附录 B"标准资源包消息"显示了一些示例:
javax.validation.constraints.Min.message=must be greater than or equal to {value}
javax.validation.constraints.Max.message=must be less than or equal to {value}
javax.validation.constraints.Size.message=size must be between {min} and {max}
javax.validation.constraints.Digits.message=numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected)
因此,命名参数似乎是您应该使用的方式。({0}
,{1}
和{2}
也可以工作,似乎是一个实现"功能"( - 但最终,这只是默认消息插值器的行为,标准定义了如何用您自己的替换它们的方法。
更新
Hibernate验证实现具有附加功能,可以将值格式化${validatedValue:<format>}
- 也许这对您的java.lang.NumberFormatException
有所帮助
@See 休眠验证器参考,第 5.3 章。消息插值器
- 对于
Size.foo.bar
名称插值不起作用 - 但是,对于
size.foo.bar
和baz.foo.bar
它确实如此(当不使用验证注释名称时;检查区分大小写(
使用message.properties
文件进行检查,该文件WebAppConfig
扩展WebMvcConfigurerAdapter
如下:
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
@Override
public Validator getValidator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
更好的使用:
@Size(max=99)
@NotBlank
private String title;
因为@Size
允许空格字符,如空格(
(。