ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
メッセージ式とは
Thymeleaf の #{...} は、テンプレート内に直接文字列を書くのではなく、外部のプロパティファイルから読み込む仕組みです。これにより (1) 多言語対応 (i18n)、(2) 翻訳作業をデザイナと分業、(3) 文言変更時にテンプレート再ビルド不要といった利点があります。
最小サンプル
1. messages.properties (デフォルト)
# src/main/resources/messages.properties
home.title=ホーム
home.welcome=ようこそ
home.button.login=ログイン
home.button.signup=新規登録
article.title=記事タイトル
article.body=本文
article.created_at=作成日時
error.required={0} は必須です
error.minLength={0} は {1} 文字以上で入力してください
2. テンプレート
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="#{home.title}">ホーム</title>
</head>
<body>
<h1 th:text="#{home.welcome}">ようこそ</h1>
<button th:text="#{home.button.login}">ログイン</button>
<button th:text="#{home.button.signup}">新規登録</button>
</body>
</html>
多言語対応 (i18n)
ファイル命名規約
| ファイル名 | 適用条件 |
|---|---|
messages.properties | デフォルト (どのロケールにも該当しない時) |
messages_ja.properties | 日本語 |
messages_en.properties | 英語 |
messages_en_US.properties | アメリカ英語 |
messages_zh_CN.properties | 簡体字中国語 |
サンプル
# messages_ja.properties
home.title=ホーム
home.welcome=ようこそ
home.button.login=ログイン
# messages_en.properties
home.title=Home
home.welcome=Welcome
home.button.login=Login
# messages_zh_CN.properties
home.title=主页
home.welcome=欢迎
home.button.login=登录
application.properties
# 既定で messages という basename を読みます。明示も可
spring.messages.basename=messages
# 複数の basename を読む場合
# spring.messages.basename=messages,errors,validation
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=false
spring.messages.use-code-as-default-message=true
ロケール切替の方法
Spring MVC はロケール解決を 3 つの方法で行えます:
// 1. URL パラメータ ?lang=en で切替
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.JAPANESE);
return resolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang"); // ?lang=en
return interceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
// 2. Accept-Language HTTP ヘッダ
// AcceptHeaderLocaleResolver (Spring Boot のデフォルト)
// 3. クッキー
// CookieLocaleResolver
引数つきメッセージ
# messages.properties
greeting=こんにちは {0} さん、{1} 件の通知があります
error.required={0} は必須項目です
error.range={0} は {1} 以上 {2} 以下で入力してください<!-- テンプレート -->
<p th:text="#{greeting(${user.name}, ${notificationCount})}">
こんにちは ゲスト さん
</p>
<p th:text="#{error.required('メールアドレス')}">
必須エラー
</p>
<p th:text="#{error.range('年齢', 0, 120)}">
範囲エラー
</p>
属性へのメッセージ展開
<!-- placeholder にメッセージ -->
<input type="text"
th:placeholder="#{form.name.placeholder}"
th:title="#{form.name.title}">
<!-- 文字列連結 -->
<a th:text="|#{home.welcome}, ${user.name}!|">Welcome, taro!</a>
<!-- 複数属性の一括 -->
<input type="text"
th:attr="placeholder=#{form.placeholder}, title=#{form.title}">
テキスト中に直接埋め込み
<!-- [[ ]] = th:text、[( )] = th:utext と同義 -->
<p>[[#{home.welcome}]] さん</p>
<!-- 条件・繰り返しと組み合わせ -->
<th:block th:if="${count > 0}">
<p th:text="#{notifications.summary(${count})}">通知あり</p>
</th:block>
Controller で MessageSource を直接使う
@RestController
public class ApiController {
private final MessageSource messageSource;
public ApiController(MessageSource messageSource) {
this.messageSource = messageSource;
}
@GetMapping("/api/hello")
public String hello(Locale locale) {
return messageSource.getMessage("home.welcome", null, locale);
}
@GetMapping("/api/error")
public String error(Locale locale) {
return messageSource.getMessage(
"error.required",
new Object[]{"メールアドレス"},
locale
);
}
}
UTF-8 設定 (文字化け対策)
古い Spring では messages_ja.properties を Unicode エスケープ (こん...) する必要がありました。Spring Boot 1.4+ では UTF-8 がデフォルトですが、明示推奨:
# application.properties
spring.messages.encoding=UTF-8
spring.thymeleaf.encoding=UTF-8
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
FAQ
Q: ??home.welcome_ja_JP?? と表示される
A: メッセージキー未定義。messages.properties に定義漏れか、basename 設定ミス。
Q: HTML タグを含むメッセージを出したい
A: th:utext="#{key}" でエスケープ無効化。XSS 注意。
Q: 改行をメッセージに入れたい
A: properties に \n と書き、テンプレートで style="white-space:pre-line" で改行を表示。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
- 導入方法と基本動作
- メッセージ式
- テンプレートフラグメント(ヘッダー等の共有化)
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?