3

サインアップ登録フォームモデルでユーザー資格情報を定義する単純な 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' は {1} にバインドされ、'min' は {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

私はとてもばかです。コード内メッセージを忘れて、適切に補間されたと思いました。もう。ですから、アルファベット順です... これ以上は求められないと思います。

4

1 に答える 1

5

Spring 3.0.4から実際の順番はアルファベット順(「max」は「min」より小さい)だと思います。

SPR-6730 の議論から (Juergen Hoeller の投稿)

最初のオプションでは、Spring 管理のフィールド エラー引数に実際の制約アノテーション属性がアルファベット順に含まれるようになりました。したがって、 @Size(min=1,max=5) の場合、フィールド名は {0} として、最大値は {1} として、最小値は {2} として含まれます。

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

于 2012-12-09T20:10:46.780 に答える