java - spring/hibernate JSR-303(Bean 验证)本地化消息中的命名参数

标签 java spring localization bean-validation hibernate-validator

我有一个在注册表单模型上定义用户凭据的简单 bean:

public class UserCreds {
    @Length(min=1, max=50)
    @NotEmpty
    private String username;

    @Email
    private String email;

    @NotEmpty
    @Length(min=1, max=50)
    private String password;

    private String passwordConfirm;

    ... only obvious getters and setters below this line ...
}

我在“userCreds”模型属性下传递它的实例,所以我有以下本地化包:

NotEmpty.userCreds.username=Username is required
NotEmpty.userCreds.password=Passsword is required
Length.userCreds.username=Username length must be between {2} and {1} symbols
Length.userCreds.password=Password length must be between {2} and {1} symbols
Email.userCreds.email=Ill-formed e-mail address

而且有效!

这里的问题:我不想使用这个神秘的 {N} 占位符,它们可能会偶尔改变它们的位置(在上面的包中,'max' 绑定(bind)到 {1} 并且 'min' 绑定(bind)到 {2},这至少是不明显的定位)我希望使用注释的全名,如

Length.userCreds.username=Username length must be between {min} and {max} symbols

(这不起作用 - 当我尝试它时 - 我得到 java.lang.IllegalArgumentException: can't parse argument number min 异常)

正如我在代码中定义消息时所做的那样(以下示例也有效):

@Length(min=1, max=50, message = "Username length must be between {min} and {max} symbols")
@NotEmpty
private String username;

但是当我在代码中定义它时,我失去了将消息本地化为不同语言的能力。

做什么?

更新 1

<罢工> 在我的 IDE 中调试调试器几个小时后,我发现使用以下类:

public class BakaMessageSource extends ReloadableResourceBundleMessageSource {

    @Override
    protected MessageFormat resolveCode(String code, Locale locale) {
        /* original implementation *
        for (String basename : basenames) {
            List<String> filenames = calculateAllFilenames(basename, locale);
            for (String filename : filenames) {
                PropertiesHolder propHolder = getProperties(filename);
                MessageFormat result = propHolder.getMessageFormat(code, locale);
                if (result != null) {
                    return result;
                }
            }
        }
        */
        return null;
    }
}

使用以下 spring-servlet.xml 声明:

<bean id="messageSource" class="org.eientei.radiorandom.framework.crutchy.BakaMessageSource"
          p:defaultEncoding="UTF-8"
          p:alwaysUseMessageFormat="false"
            >
        <property name="basenames">
            <list>
                <!-- my application-specific localization bundles -->
                <value>classpath:messages/root/errorMessages</value>
                <value>classpath:messages/root/langMessages</value>
                <value>classpath:messages/user/signupMessages</value>
            </list>
        </property>
    </bean>

代替原始的 ReloadableResourceBundleMessageSource 实际上有助于获取具有命名参数的本地化消息。

但我想在那个时候交换类并不是一个合适的解决方案。哪一个会是?

更新 2

我真是个笨蛋。我忘记了代码内消息并认为它已正确插入。哎呀。 所以,按字母顺序排列……我想我不能要求更多了。

最佳答案

我认为从 Spring 3.0.4 开始,实际顺序是按字母顺序排列的(“max”小于“min”)。

来自 SPR-6730 讨论(Juergen Hoeller 发布)

For the first option, Spring-managed field error arguments include the actual constraint annotation attributes in alphabetical order now. So for @Size(min=1,max=5), it'll include the field name as {0} , the max value as {1} , and the min value as {2}

参见 https://jira.springsource.org/browse/SPR-6730

关于java - spring/hibernate JSR-303(Bean 验证)本地化消息中的命名参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13790987/

相关文章:

qt - 如何本地化 Qt qmldir 插件?

java - Spring OAuth2 认证服务器 : a specific/oauth/token filter?

.net - 覆盖程序集中特定资源文件的中性语言

ios - 如何通过 FaSTLane 脚本添加 Xcode 本地化语言

java - MySQL: "error in your SQL syntax"的来源

java - 无论如何,有没有办法在 spring mvc 中调用没有 .html 扩展名的rest api

Java 1.8u20 无法启动 spring boot 和 groovy 2.3.7

Java-如何使用文档过滤器限制输入数字范围?

java - 无法连接到 ssl 服务器收到致命警报 : certificate_unknown and ReadDataRecord(SSLSocketImpl

java - 为什么在向下转换时在编译时不抛出 classcastException?