Thymeleaf JavaScriptのinlineの仕組みと活用法
新人
「先輩、ThymeleafのJavaScript inlineってよく出てきますけど、どういうものなんですか?」
先輩
「JavaScript inlineは、Thymeleafのテンプレート内でサーバーサイドの値を直接JavaScriptに埋め込む仕組みだよ。pleiades環境でも簡単に使えるから、基本を覚えておくと便利だよ。」
新人
「具体的にどう書くんですか?コントローラで渡した値をJavaScriptで使う方法を知りたいです。」
先輩
「それじゃあ、JavaScript inlineの仕組みと書き方から順番に説明していくね!」
1. Thymeleaf JavaScript inlineとは?
ThymeleafのJavaScript inlineとは、サーバーサイドで生成されたデータをクライアントサイドのJavaScriptに直接埋め込む仕組みです。例えば、Spring MVCのコントローラでモデルに値を設定し、それを画面のJavaScriptで使うときに便利です。pleiades環境+Gradleのプロジェクトでも同じように使えます。
JavaScript inlineでは、th:inline="javascript"を指定して、サーバーサイドの値を[[ ]]構文で安全にJavaScriptに渡します。これにより、画面表示に必要なデータをJavaScriptで活用できます。
2. JavaScript inlineを使う理由と基本の使い方
JavaScript inlineを使う理由は、サーバーサイドの値をブラウザで動的に扱えるようにするためです。JavaScriptに値を埋め込むことで、例えば画面の動的な切り替えや条件分岐などを簡単に実現できます。
基本的な使い方は以下の通りです。まず、HTMLテンプレートの<script>タグにth:inline="javascript"を付けます。そして、サーバーサイドの値は[[ ]]構文を使って埋め込みます。文字列は引用符で囲むのを忘れないようにしましょう。
<script th:inline="javascript">
var count = [[${count}]];
var message = "[[${message}]]";
console.log("回数:" + count + "、メッセージ:" + message);
</script>
この例では、countという数値と、messageという文字列をJavaScriptに渡しています。pleiades環境でも、同じ手順で記述すればすぐに動かせます。
3. コントローラからの値の渡し方とJavaScriptへの受け取り例
それでは、具体的にコントローラから値を渡して、JavaScriptで受け取る方法を見ていきましょう。まず、Spring MVCのコントローラを@Controllerで作成します。
@Controller
public class InlineController {
@GetMapping("/inline-demo")
public String inlineDemo(Model model) {
model.addAttribute("count", 5);
model.addAttribute("message", "ようこそThymeleafの世界へ!");
return "inline-demo";
}
}
この例では、モデルにcountとmessageという値をセットしています。次に、inline-demo.htmlのテンプレートでJavaScript inlineを使って受け取ります。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>JavaScript inlineの基本</title>
</head>
<body>
<h2>JavaScript inlineのデモ</h2>
<script th:inline="javascript">
var count = [[${count}]];
var message = "[[${message}]]";
for (var i = 0; i < count; i++) {
console.log(message + " (" + (i+1) + ")");
}
</script>
</body>
</html>
このように書くと、サーバー側のcountとmessageがJavaScriptに正しく渡され、ブラウザのコンソールにメッセージが繰り返し出力されます。JavaScript inlineの仕組みを覚えれば、複雑な動的処理も簡単に作れるようになります。
さらに、文字列は必ず引用符で囲むようにする、数値はそのまま埋め込むなどの基本ルールを守ることで、エラーを防ぎやすくなります。pleiades環境でも同じ手順で試せますので、ぜひ実際に試してみてください。
4. 変数の埋め込みと型の扱い方
JavaScript inlineでThymeleafの変数を埋め込む場合、データの型に注意することが重要です。数値と文字列、配列やオブジェクトなどを適切に扱うことで、意図した動きが得られます。
まず数値の場合、[[ ]]構文でそのまま埋め込めば型はそのままJavaScriptの数値として認識されます。
<script th:inline="javascript">
var count = [[${count}]];
console.log(typeof count); // "number"
</script>
文字列の場合は引用符で囲む必要があります。囲まないとSyntaxErrorになったり変数展開されないことがあるため注意してください。
<script th:inline="javascript">
var msg = "[[${message}]]";
console.log(typeof msg); // "string"
</script>
配列やオブジェクトを渡す場合は、コメント付き構文(/*[[...]]*/)を利用します。JSONとして展開されるため、そのまま配列やオブジェクトとして使えます。
<script th:inline="javascript">
var items = /*[[${items}]]*/ [];
console.log(Array.isArray(items)); // true
</script>
このように型ごとに適切な構文を使い分けることで、JavaScript内で型エラーや予期せぬ動作を減らせます。
5. よくあるエラー例とその解決策
初心者がThymeleaf inlineを使うときによく遭遇するエラーと、その解決方法をいくつか紹介します。
文字列の引用符忘れ
引用符を付けずに文字列値を埋め込むとエラーになります。
<script th:inline="javascript">
var name = [[${name}]]; // NG
</script>
正しくは以下のように引用符で囲みます。
<script th:inline="javascript">
var name = "[[${name}]]"; // OK
</script>
配列が文字列として扱われる
/*[[...]]*/を使わずJSONが展開されないと、配列が文字列になってしまいます。必ずコメント付き構文で展開しましょう。
<script th:inline="javascript">
var fruits = /*[[${fruits}]]*/ []; // OK
</script>
型変換忘れ
数値として扱いたいのに文字列として受け取ってしまうケースです。parseIntやparseFloatで変換してから使いましょう。
<script th:inline="javascript">
var count = "[[${count}]]";
count = parseInt(count);
</script>
Grasp構文とJS構文の衝突
scriptタグにth:inline="javascript"がないと、[[ ]]構文が展開されず、構文エラーになります。必ずinline属性を付けてください。
6. 実践例:動的な表示や処理での活用
ここでは、JavaScript inlineを使って動的なリスト表示やユーザー操作に応じた処理を行う実践例を紹介します。
動的リストの表示
コントローラでモデルにリストを渡し、JavaScriptでリストをレンダリングします。
@Controller
public class FruitController {
@GetMapping("/fruits")
public String fruits(Model model) {
model.addAttribute("fruits", Arrays.asList("りんご", "みかん", "バナナ"));
return "fruits";
}
}
<script th:inline="javascript">
var fruits = /*[[${fruits}]]*/ [];
fruits.forEach(function(fruit) {
var p = document.createElement("p");
p.textContent = "果物:" + fruit;
document.body.appendChild(p);
});
</script>
この方法なら、ThymeleafのModelから受け取ったデータをJavaScriptで自由に操作でき、簡単な動的UIが作れます。
ボタンクリックで処理を切り替える
サーバーでフラグを渡し、その値で処理内容を変えるサンプルです。
@Controller
public class FlagController {
@GetMapping("/flag-demo")
public String demo(Model model) {
model.addAttribute("isAdmin", true);
return "flag-demo";
}
}
<script th:inline="javascript">
var isAdmin = [[${isAdmin}]];
document.getElementById("btn").addEventListener("click", function(){
if(isAdmin){
alert("管理者用処理を実行します");
} else {
alert("一般ユーザー用処理です");
}
});
</script>
このように、サーバーの状態をJavaScript側に渡すことで、画面を動的に制御できます。
7. セキュリティ面での注意点と安全な使い方
JavaScript inline を使うと、サーバー側の値がそのままブラウザに渡ります。そのため、意図しない情報漏えいやクロスサイトスクリプティング(XSS)につながる可能性があります。ここでは安全に扱うためのポイントを解説します。
HTML エスケープと Thymeleaf のデフォルト動作
Thymeleaf はデフォルトで値を HTML エスケープしますが、JavaScript inline では JSON 形式で展開されるため、スクリプトとして扱われやすくなります。信頼できないデータ(ユーザー入力など)は必ずサニタイズしてから渡すようにしてください。
th:inline 属性を意図的に使用
th:inline="javascript" を指定することで、Thymeleaf が構文を解釈して安全に展開します。意図せずに構文が展開されないよう、スクリプト内には必ず inline 属性を明示しましょう。
データの検証とバリデーション
モデルにセットする前に、サーバー側で値のチェックとバリデーションを行ってください。例えば、数値が本当に数値か、文字列に不正なスクリプトタグが含まれていないかなどを検証しましょう。
@Controller
public class SecureController {
@GetMapping("/secure")
public String secure(Model model) {
String userInput = getUserInput();
// サニタイズ処理(例として)
String safeText = HtmlUtils.htmlEscape(userInput);
model.addAttribute("safeText", safeText);
return "secure";
}
}
定数の扱いなら JavaScript に直接書く
変更されない定数やメッセージは Thymeleaf ではなく、JavaScript ファイルやスクリプトに直接記述したほうが安全です。動的に使う値だけを inline で渡すようにしましょう。
8. まとめポイントと活用のコツ
ここまでの内容を振り返り、初心者でもわかりやすく JavaScript inline を安全に使うための重要ポイントを整理します。
- th:inline を必ず指定して構文展開を正しく行う
- 数値、文字列、配列・オブジェクトはそれぞれ正しい構文で渡す([[${}]]、"[[${}]]"、/*[[${}]]*/)
- 信頼できないデータはサーバー側でバリデーション・エスケープを実施
- スコープ汚染を防ぐために IIFE(即時実行関数)などを活用
// 即時関数でスコープを閉じ込める例
<script th:inline="javascript">
(function(){
var msg = "[[${message}]]";
console.log(msg);
})();
</script>
このように工夫すれば、スクリプトの可読性と安全性が向上します。
9. 実践的なヒントと今後の学び方
最後に、JavaScript inline を実務で活用するためのヒントと、さらに学びを深めるためのポイントを紹介します。
デバッグするときの工夫
ブラウザ開発者ツールを活用して、展開された変数が正しく JavaScript に渡されているかを確認しましょう。console.log を入れることで、どんな値が渡されたか一目でわかります。
ユニットテストとの共存
サーバー側でモデルにセットするロジックはユニットテストを書いておくと安心です。値の型や null チェックが正しく行われているかをテストしましょう。
今後の学び方
JavaScript inline は小さな値やフラグの受け渡しに便利ですが、大きなアプリでは外部 API を呼ぶ方法に切り替えることも考慮しましょう。Spring MVC で REST API を作り、JavaScript 側から fetch で非同期通信する方法も学ぶと応用力がつきます。
また、Thymeleaf の拡張機能やユーティリティサポート(#arrays、#dates など)も調べておくと、より高度なテンプレート制御が可能になります。
今回の内容をベースに、pleiades+Gradle 環境で実際にコードを書いて試してみてください。慣れてくれば、画面とロジックの連携をさらに強化できるようになります。