9

我目前正在尝试使用 bean 验证提供自定义验证消息。

目前使用 spring mvc 3.1.1 + apache bean 验证。

在我的 bean 中,我指定:

@Size(min=1, max=50)
private String title;

在我的 messages.properties 中:

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.基于默认的 ValidationMessages.properties 尝试使用,但最终在{max}. 我认为这与插值有关?


更新

因此,这些中的每一个都因 NumberFormatException 而独立失败{max}

  • messages.properties : Size.addForm.title=标题不能为空且不能超过{max}个字符。
  • messages.properties : Size=标题不能为空且不能超过{max} 个字符。
  • messages.properties : javax.validation.constraints.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.constraints.Size.message=你知道wad,大小必须在{min}{max}之间

基本上目前的结论是,默认情况下,我不能在我的特定消息上使用命名参数。命名参数在我使用相同的默认 jsr303 资源包文件名(即ValidationMessages.properties )覆盖默认 jsr303 资源包&&上的确切键时才有效

我现在更喜欢避免使用插值,因此关于如何找出 {0} 或 {1} 或 {2} 的原始问题是指文档中的内容。

4

3 回答 3

4

JSR 303 规范,4.3.1.1。“默认消息插值算法”

  • 4 - 从消息字符串中提取消息参数。那些与约束的属性名称匹配的那些将替换为约束声明中该属性的值。

我是这样读的:您应该为消息参数使用注释属性的名称,而不是数字。

规范的附录 B“标准 ResourceBundle 消息”显示了一些示例:

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 Validation 实现接缝具有格式化值的附加功能${validatedValue:<format>}。-- 也许这对你有帮助java.lang.NumberFormatException

@参见Hibernate 验证器参考,第 5.3 章。消息内插器

于 2012-05-05T17:49:25.933 回答
0

更好的使用:

    @Size(max=99)
    @NotBlank
    private String title;

因为@Size允许空白字符,如空格( )。

于 2016-04-05T12:42:13.080 回答
0
  • 带有名称的Size.foo.bar插值不起作用
  • 但是 forsize.foo.bar并且baz.foo.bar确实如此(当不使用验证注释名称时;检查区分大小写)

使用扩展message.properties中添加的文件进行检查,例如:WebAppConfigWebMvcConfigurerAdapter

  @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;
  }
于 2017-09-27T14:46:56.003 回答