The orders of bean validation default parameters?

霸气de小男生 提交于 2019-12-12 08:33:14

问题


I am currently trying to provide a custom validation message using bean validation.

Currently using spring mvc 3.1.1 + apache bean validation.

In my bean, i specify :

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

And in my messages.properties :

Size.addForm.title=The title must not be empty and must not exceed {1} characters.

From experiment, i found out that :

  • {0} refers to 'title'
  • {1} refers to the max, which is 50
  • {2} refers to the min, which is 1

and it'll be displayed as The title must not be empty and must not exceed 50 characters. which is correct.

But all these are from experiments. I wonder whether there are documentations stating the order of parameters for the default constraints ?

I tried hopefully using Size.addForm.title=The title must not be empty and must not exceed {max} characters. basing on the default ValidationMessages.properties but ends up with NumberFormatException on the {max}. I think it has something to do with the interpolations ?


Update

So, each of these fails independently with NumberFormatException on the {max} :

  • messages.properties : Size.addForm.title=The title must not be empty and must not exceed {max} characters.
  • messages.properties : Size=The title must not be empty and must not exceed {max} characters.
  • messages.properties : javax.validation.constraints.Size.message=The title must not be empty and must not exceed {max} characters.
  • ValidationMessages.properties : Size.addForm.title=The title must not be empty and must not exceed {max} characters.
  • ValidationMessages.properties : Size=The title must not be empty and must not exceed {max} characters.

This is the stacktrace :

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)

This is the only one that works with the named parameter, it has to be ValidationMessages.properties, and it has to be exactly the key that exists in the default resource bundle by the jsr 303 implementation :

  • ValidationMessages.properties : javax.validation.constraints.Size.message=you know wad, the size must be between {min} and {max}

Basically the current conclusion is, by default, i cannot use named parameters on my specific messages. The named parameter only works when i override the exact key on the default jsr303 resourcebundle && when i use the same default jsr303 resourcebundle file name, which is ValidationMessages.properties

I prefer avoiding having to play with interpolation for now, hence the original question on how to find out that {0} or {1} or {2} refers to what in the documentation.


回答1:


JSR 303 Specification, 4.3.1.1. "Default message interpolation algorithm"

  • 4 - Message parameters are extracted from the message string. Those matching the name of an attribute of the constraint are replaced by the value of that attribute in the constraint declaration.

I read this like: you should use the name of the annotation properties for the message parameter, instead of numbers.

Appendix B "Standard ResourceBundle messages" of the specification shows some examples:

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)

So it seems that named paramerter are the way you should use. (That {0}, {1} and {2} works too, seems to be a implementation "feature") - But in the end, this is only the behavior of the default message interpolator, the standard defines a way how to replace them by your own.


Update

The Hibernate Validation implementation seams to have an additional feature to format values ${validatedValue:<format>}. -- Maybe that helps you with your java.lang.NumberFormatException

@See Hibernate Validator Reference, Chapter 5.3. MessageInterpolator




回答2:


Better use:

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

cause @Size allows Whitespace characters like space




回答3:


  • for Size.foo.bar interpolation with names doesn't work
  • however for size.foo.bar and baz.foo.bar it does (when validation annotation name isn't used; check is case sensitive)

Checked with message.properties file which is added in WebAppConfig extending WebMvcConfigurerAdapter like:

  @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;
  }


来源:https://stackoverflow.com/questions/10461945/the-orders-of-bean-validation-default-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!