草庐IT

java - bean validation命令的默认参数?

coder 2024-03-13 原文

我目前正在尝试使用 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

它会显示为 标题不能为空且不能超过 50 个字符。 这是正确的。

不过这些都是实验出来的。我想知道是否有文档说明默认约束的参数顺序

我希望使用 Size.addForm.title=The title must not be empty and must not exceed {max} characters. 基于默认的 ValidationMessages.properties 但最终在 {max}。我认为这与插值有关?


更新

因此,这些中的每一个都独立地失败并在 {max} 上出现 NumberFormatException :

  • 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 资源包文件名时,命名参数仅在我覆盖默认 jsr303 资源包 && 上的确切键时有效,这是 ValidationMessages.properties

我宁愿暂时避免使用插值,因此关于如何找出 {0} 或 {1} 或 {2} 的原始问题指的是文档中的内容。

最佳答案

JSR 303 Specification , 4.3.1.1。 《默认消息插值算法》

  • 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.

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

规范的附录 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 Validator Reference, Chapter 5.3. MessageInterpolator

关于java - bean validation命令的默认参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10461945/

有关java - bean validation命令的默认参数?的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  4. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  5. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  6. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  7. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  8. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  9. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  10. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

随机推荐