[Spring Boot + Thymeleaf] 固定の文字列などをプロパティファイルで管理する

# 本記事でわかること
本記事では以下について記載いたします。
* 固定の文言をmessages.propertiesに記載し、外出しにする方法
* html、javaでプロパティ値を取得する方法
* messages.propertiesの配置パスを変更する方法

# 固定の文字列などをプロパティファイルで管理する
画面の表示内容では、ヘッダー内のタブ名など、しばしば固定の文言を出力することがあります。
そういったときに、表示するテキストをhtmlファイルにべた書きしてしまうと、以下のような不都合が生じます。
* 固定文言の修正が困難になる。プロジェクト内で固定の文言がある場所をわざわざ検索をかけ、手作業で一つずつ消していく羽目になる。
* 管理がしにくくなる。固定の文言をべた書きしたまま、そのhtmlファイルを使いまわしたりしてコードを書いていくと、後の修正で漏れが発生したり、一部のページだけ文言が微妙に異なったりする。

そのため、固定の文言についてはプロパティファイル化したりDBのデータとして持つなど、コード上ではなく外出しして一元管理するのが基本ではないでしょうか。

今回はそんな固定文言について、「messages.peroperties」ファイルを使って、外だしで管理する方法を記載していきます。

# messages.propertiesについて
今回紹介する方法は「messages.properties」ファイルにプロパティとして設定したい値を記述していく方法です。

SpringBootではデフォルトの設定で「/src/main/resources/messages.properties」を読み込みようになっています。
こちらに記載した内容はアプリ起動時にSpring側が勝手に読み込んでくれて、ThymeleafやMessageSourceクラスを利用してその値を読み取ることができます。

この方法で、「固定の文言についてはmessages.propertiesに記述する」ことでhtmlファイルやjavaコード上にべた書きする必要がなくなるわけです。

# messages.propertiesの作成
さっそく実践していきましょう。
「/src/main/resources」の配下に「messages.properties」を作成します。
eclipseなら「右クリック」→「新規」→「ファイル」で、ファイル名に「messages.peroperties」と記載して作成すれば完了です。

ファイル作成箇所は **必ず** 「/src/main/resources」配下です。別途設定すれば読み込みファイルパスは変更可能（やり方は後述）ですが、デフォルトは上記パスのためいったんルールに則りましょう。

ファイルツリーはこんな感じ。

```
/src
 -/main
  -/resources
   -/messages.properties
```

作成したファイルに固定文言を記載していきます。
記載方法は変数の宣言とほぼ同じ形です。
```
${キー名}=${値}
```

サンプルプログラムで使用するプロパティは以下になります。htmlに出力するタイトルやボタン用の文言を記載しています。
```properties:messages.properties
user.page.title=ユーザー登録
userId=ユーザーID
password=パスワード
user.btn=クリック
agree=賛成
oppose=反対
```

# htmlで取得する
messages.propertiesに設定した値はth属性の値に **#{キー名}** と記載すれば取得できます。

以下に例を記載します。formタグなどは省略しています。
```html:sample.html
<!DOCTYPE html>
<head>
<!-- タイトルに「ユーザー登録」と設定される -->
<title th:text="#{user.signup.title}"></title>
</head>

<body>
<!-- label属性のテキストで「ユーザーID」「パスワード」と設定される -->
<label for="userId" th:text="#{userId}"></label>
<label for="password" th:text="#{password}"></label>

<!-- ボタンに「クリック」と表示される -->
<input type="submit" th:value="#{user.btn}" />
</body>
```

# javaで取得する
htmlだけでなくjavaからもmessages.propertiesの値を取得できます。
「org.springframework.context.MessageSource」のgetMessageメソッド呼び出しで取得できます。

[getMessageメソッド]
```tex:
getMessage(${キー名},${埋め込みパラメータ},${ロケール})
```
ロケールについては割愛しますが、ひとまず日本国内利用であれば「Locale.Japan」固定で問題ないです。

実例は以下です。「賛成」か「反対」をラジオボタンでユーザーに押してもらうために、htmlに設定するマップを作成しています。
```java:SampleController.java
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;

@Service
public class SampleController {

	@Autowired
	private MessageSource messageSource;
	
	@GetMapping("/signup")
	public String getSignUp(Model model) {
		
		Map<String,Integer> map=new HashMap<>();
		String agree = messageSource.getMessage("agree", null, Locale.JAPAN);
		String oppose = messageSource.getMessage("oppose", null, Locale.JAPAN);
		
		map.put(agree, 1);
		map.put(oppose, 2);
		model.addAttribute("sampleMap",map);

		return "user/signup";
	}
}
```

あとはmapに設定した内容をhtmlで出力するように記載しましょう。
[th属性の使い方についてはこちら](https://qiita.com/sinoofgan/items/d81063b5eda6664a3d1a#theach "リンク先")にもサンプル記載していますので、各th属性の使い方については割愛します。

```html:sample.html
	<form id="signup-form" class="form-signup" method="post" th:action="@{/user/signup}"
		th:object="${sampleForm}">
		<h1>サンプルページ</h1>

		<!-- ラジオボタンテキストにsampleMapのキー値が設定される -->
		<div class="form-group">
			<div th:each="item:${sampleMap}" class="form-check-inline">
				<input type="radio" class="form-check-input" th:value="${item.value}" name="vote"/> 
				<label class="form-check-label" th:text="${item.key}"></label>
			</div>
		</div>
	</form>
```

# messages.propertiesの値を埋め込みパラメータで補完する
getMessagesメソッドのパラメータにあった「埋め込みパラメータ」の使い方を記載します。

前述したサンプルを埋め込みパラメータで実装する場合は、javaからプロパティの値を設定するように記載します。

```properties:messages.properties
agree={0}
```

```java:SampleController.java
String agree = messageSource.getMessage("agree", new String[]{"賛成"}, Locale.JAPAN);
```

# messages.propertiesの配置パスを変更する
プロパティファイルは「/src/main/resources」配下を参照すると前述しましたが、このパスは設定で変更することができます。

試しに「/src/main/resources/sample」配下にプロパティファイルを移動したいと思います。

application.propertiesの「spring.messages.basename」の値を変更します。
以下で「/src/main/resources/sample/messages.properties」をプロパティファイルとして設定できます。
```
${/src/main/resourcesとの相対パス}/${拡張子を除いたファイル名}
```

```properties:messages.properties
spring.messages.basename=sample/messages
```

ファイルツリーは以下のようになります。
```
/src
 -/main
  -/resources
   -/sample
    -/messages.properties
```

# まとめ
本記事では以下について記載しました。閲覧ありがとうございました。
* 固定の文言をmessages.propertiesに記載し、外出しにする方法
* html、javaでプロパティ値を取得する方法
* messages.propertiesの配置パスを変更する方法