サインアップ登録フォームモデルでユーザー資格情報を定義する単純な 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
私はとてもばかです。コード内メッセージを忘れて、適切に補間されたと思いました。もう。ですから、アルファベット順です... これ以上は求められないと思います。