properties ファイルの値を動的に取得する方法
現在のプロジェクトではあまり一般的ではない、そして古い思想のフレームワーク (フレームワークと呼べるようなモノではなく、単に基盤といった感じ) を利用しているため、メッセージ出力部分が非常に貧相です。そこで Java の標準的なやり方でメッセージファイルを外出しにして、java.util.Properties クラスを利用して値を取得、表示するように実装しました。
このようなことは過去にも何度もやっているのですが、少しだけ悩んでしまいました。メッセージファイル (ここでは messages.properties) ファイルに次のような記述があった場合、{0} や {1} にどうやって任意の値を流し込んで、全体のメッセージを取得するか、ということです。
warn.1001 = 接続に失敗しました。 warn.1002 = このフィールドは {0}〜{1} の長さを持つ必要があります。
messages.properties 自体の読み込みは java.util.Properties クラスだけでできるのですが、フォーマットを加えるとなるとそうはいかないわけで、どうやるのかを忘れてしまいました。結果的には java.text.MessageFormat クラスを利用すれば解決です。
import java.io.InputStream; import java.text.MessageFormat; import java.util.Properties; public class MessageTester { public void run() throws Exception { // message.properties ファイル final InputStream inputStream = this.getClass().getClassLoader() .getResourceAsStream("messages.properties"); Properties props = new Properties(); // ファイルをロードする props.load(inputStream); // シンプルなメッセージ出力 System.out.println(props.getProperty("warn.1001")); // 引数を与えてフォーマットしてメッセージ出力 System.out.println(MessageFormat.format(props.getProperty("warn.1002"), "8", "32")); } public static void main(String[] args) throws Exception { MessageTester tester = new MessageTester(); tester.run(); } }
実行結果はこちら。
接続に失敗しました。 このフィールドは 8〜32 の長さを持つ必要があります。
単純なメッセージ出力は
System.out.println(props.getProperty("warn.1001"));
これで大丈夫です。次にフォーマットの場合。
System.out.println(MessageFormat.format(props.getProperty("warn.1002"), "8", "32"));
MessageFormat#format は第1引数にフォーマット対象となる文字列を、それ以降の引数で流し込む値を指定してやります。第2引数は可変長引数として定義されていますので、必要なだけ与えてやることができます。ここでは "8" が {0} に、"32" が {1} に入り、結果的に「このフィールドは 8〜32 の長さを持つ必要があります。」と出力されます。
いつもやっていることなのにいざというときに思い出せない、こんなことで時間を使いたくないですね〜。ということで未来の自分のためのメモエントリでした。