Thymeleaf null判定の書き方!初心者向けにやさしく解説
新人
「先輩、Thymeleafで値がnullのときにエラーが出ることがあるんですが、どうすれば防げますか?」
先輩
「ああ、それはThymeleafのnull判定を使えば簡単に解決できるよ。nullチェックを行えば、データがない場合でも安全に画面を表示できるんだ。」
新人
「null判定って具体的にどんな書き方をするんですか?」
先輩
「じゃあ今回は、Thymeleafのnull判定の書き方を基本から見ていこう。特にth:ifやth:unlessの使い方を覚えると便利だよ。」
1. Thymeleafとは?
Thymeleaf(タイムリーフ)は、Spring Frameworkでよく使われるテンプレートエンジンです。HTMLファイルの中で変数を埋め込んだり、条件分岐を行ったりして、動的にページを生成できます。初心者の方でも、HTMLの構文に近い書き方で直感的に使えるのが特徴です。
開発環境はpleiades+Gradle+@Controller構成を前提にしています。Spring Bootを使う場合も同様に設定できますが、この記事ではあくまでThymeleafのnull判定に焦点をあてて説明します。
Thymeleafのテンプレートは、通常src/main/resources/templatesフォルダに配置します。拡張子は.htmlで、普通のHTMLとしてブラウザで開いてもエラーになりません。これは静的なHTMLと同じようにデザイン確認ができるという大きなメリットです。
新人
「HTMLとして開けるって便利ですね!Spring専用のタグじゃないんですか?」
先輩
「そうだね。ThymeleafのタグはHTMLに準拠しているから、静的ページとしても問題なく開けるんだ。だからデザイナーさんと分担して作業しやすいんだよ。」
2. null判定が必要になる理由
ThymeleafでWebページを作るとき、コントローラから渡されたオブジェクトがnullのままテンプレートに展開されることがあります。その場合、${user.name}のように直接アクセスするとエラーが発生します。
このエラーを防ぐために使うのが、Thymeleaf null判定です。変数が存在するかどうかを確認し、存在しない場合に代替メッセージを表示することで、エラーを防ぎつつユーザーにわかりやすいメッセージを出すことができます。
たとえば、ユーザー情報が存在する場合は名前を表示し、存在しない場合は「データがありません」と表示するなどの制御が可能です。
<span th:if="${user != null}">ユーザー名:<span th:text="${user.name}"></span></span>
<span th:unless="${user != null}">ユーザー情報がありません。</span>
上記のように、th:ifで条件が真(true)のときに表示し、th:unlessで条件が偽(false)のときに表示します。つまり、th:ifは「存在する場合」、th:unlessは「存在しない場合」の表示に使うのです。
このnull判定を正しく使うことで、Thymeleafのテンプレートを安全にレンダリングでき、エラーのない安定したアプリケーションを作れます。
新人
「もしデータベースにユーザー情報が無かったら、nullが返ってくるんですよね?」
先輩
「そう。そのときにこのnullチェックを書いておかないと、画面が壊れたり例外が発生したりするんだ。」
3. nullチェックの基本構文
Thymeleafでは、SpEL(Spring Expression Language)を利用してnull判定を行います。構文はJavaに近く、${user != null}のように書けます。条件が真の場合のみ指定したHTMLを出力する仕組みです。
基本的な構文は次のようになります。
<div th:if="${user != null}">
<p th:text="'ユーザー名:' + ${user.name}"></p>
</div>
<div th:unless="${user != null}">
<p>ユーザー情報が存在しません。</p>
</div>
ここではth:ifで「userがnullでない場合」、つまり存在する場合にユーザー名を表示しています。逆に、th:unlessは「userがnullの場合」にメッセージを出します。
どちらもテンプレート上で簡単に条件分岐を実現できるため、if文のようなJavaコードを書く必要がありません。HTMLの中で条件を完結できるのが、Thymeleafの強みです。
Springコントローラとの連携例
次に、pleiades+Gradle+@Controller構成で動作する実際のサンプルを見てみましょう。
@Controller
public class UserController {
@GetMapping("/user")
public String user(Model model) {
User user = findUser(); // データが存在しない場合はnullを返す
model.addAttribute("user", user);
return "userView";
}
private User findUser() {
// 実際にはデータベースから取得する処理を行う
return null;
}
}
このコントローラでは、findUser()メソッドでユーザー情報を取得しています。もしデータが存在しない場合、nullが返されるため、テンプレート側でnullチェックを行わないと例外が発生する可能性があります。
そのため、テンプレート内でth:ifやth:unlessを使って表示を制御するのがベストプラクティスです。
新人
「null判定を使えば、ユーザーがいないときでも安全に表示できるんですね!」
先輩
「そうだよ。これを理解しておけば、エラーを未然に防げるし、Thymeleafを使った画面開発もスムーズになるよ。」
4. 条件分岐の応用(th:ifとth:unlessの組み合わせ)
ここからは、Thymeleafの条件分岐をもう少し実践的に使う方法を見ていきましょう。基本的なth:ifとth:unlessを組み合わせることで、より柔軟な表示制御が可能になります。これにより、データの有無に応じた表示切り替えを直感的に実装できます。
例えば、ユーザー情報があるときには「ようこそ」と表示し、情報がないときには「ゲストユーザー」と表示するようなケースを考えてみましょう。
<div th:if="${user != null}">
<p th:text="'ようこそ、' + ${user.name} + 'さん!'"></p>
</div>
<div th:unless="${user != null}">
<p>ようこそ、ゲストユーザーさん!</p>
</div>
このように、th:ifとth:unlessをセットで使うことで、データの有無に応じた出力を簡単に実現できます。Springのコントローラでnullを返した場合でも、テンプレート上で安全に切り替えることができます。
また、Thymeleafではth:ifやth:unlessの中に論理演算子を使うことも可能です。複数条件を組み合わせてチェックすることもできます。
大人のユーザーとして登録されています。
未成年のユーザーです。
ユーザー情報が登録されていません。
このように条件を細かく設定すれば、同じ画面内で複数のパターンを安全に切り替えることができます。Thymeleafのth:ifとth:unlessは、テンプレートエンジンとして非常に柔軟であり、条件分岐を簡単に扱える点が魅力です。
新人
「ifとunlessを組み合わせるだけで、ここまで柔軟に制御できるんですね!」
先輩
「そうなんだ。複雑なロジックをHTMLの中で完結させられるのが、Thymeleafの便利なところだよ。」
5. 存在チェック(リストやオブジェクトの空判定)
次に、Thymeleafでの「存在チェック」について解説します。単一オブジェクトだけでなく、リストやコレクションが空かどうかを判定する場合にも、th:ifを使うことができます。例えば、ユーザー一覧を表示する場面では、データが空かどうかをチェックする必要があります。
<div th:if="${users != null and !#lists.isEmpty(users)}">
<ul>
<li th:each="u : ${users}" th:text="${u.name}"></li>
</ul>
</div>
<div th:unless="${users != null and !#lists.isEmpty(users)}">
<p>ユーザー一覧が登録されていません。</p>
</div>
このサンプルでは、#lists.isEmpty()を使ってリストが空でないことを確認しています。Thymeleafでは、#listsや#stringsといったユーティリティオブジェクトを使うことで、簡単にリストや文字列のチェックができます。
usersがnullまたは空の場合、th:unlessのブロックが実行され、「ユーザー一覧が登録されていません」と表示されます。これにより、例外を防ぎつつ、ユーザーに適切なメッセージを出すことができます。
また、null判定と空判定を同時に行うことで、どんな場合でも安全なテンプレート表示が可能になります。特に、APIや外部サービスと連携してデータを取得する画面では、このようなチェックが非常に重要です。
Springコントローラ側の実装例
@Controller
public class UserListController {
@GetMapping("/users")
public String users(Model model) {
List<User> users = findAllUsers(); // データが存在しない場合は空リストを返す
model.addAttribute("users", users);
return "userList";
}
private List<User> findAllUsers() {
return new ArrayList<>(); // 空リストを返す
}
}
上記の例では、findAllUsers()が空のリストを返しています。このような場合、テンプレート内の#lists.isEmpty()チェックが有効に働き、データがないことを安全に検知できます。
新人
「リストの判定までできるなんてすごいですね!Javaのコードみたいです。」
先輩
「そう、ThymeleafはJavaの考え方をベースにしているから直感的なんだ。リストが空かどうかを意識して書くことで、より安全なテンプレートになるんだよ。」
6. 表示制御の実例(データがある場合とない場合のHTML出力)
最後に、実際のWebページでどのようにnullチェックや存在チェックを使って表示を切り替えるかを具体的に見ていきましょう。たとえば、ユーザー詳細ページでデータが存在する場合は情報を表示し、存在しない場合は警告メッセージを出すという例です。
<div th:if="${user != null}">
<h3>ユーザー情報</h3>
<p th:text="'名前:' + ${user.name}"></p>
<p th:text="'メール:' + ${user.email}"></p>
</div>
<div th:unless="${user != null}">
<h3>データ未登録</h3>
<p>ユーザー情報が見つかりませんでした。</p>
</div>
このように、データがある場合とない場合で出力されるHTMLを完全に分けることで、画面の見た目をシンプルに保ちながらエラーを防げます。実際の開発では、条件分岐を整理しておくことでテンプレートの可読性が大きく向上します。
また、Thymeleafでは条件分岐だけでなく、th:switchを使って状態による表示切り替えもできます。たとえば、ユーザーのステータスが「ACTIVE」「INACTIVE」などで異なるメッセージを出すことも可能です。
<div th:switch="${user.status}">
<p th:case="'ACTIVE'">アクティブユーザーです。</p>
<p th:case="'INACTIVE'">現在は停止中のユーザーです。</p>
<p th:case="*">状態が不明です。</p>
</div>
このような表示制御の方法を覚えておくと、Webアプリケーション開発でのテンプレート管理がとても楽になります。特にpleiades+Gradle環境でSpring MVCを利用している場合、Thymeleafを使った安全な表示は基本中の基本です。
新人
「なるほど!条件ごとにタグを分ければ、HTMLがすっきりしますね!」
先輩
「その通り。テンプレートは整理して書くのがコツだよ。Thymeleaf null判定をマスターすれば、どんなデータでも安全に扱えるようになるよ。」
7. null判定でよくあるミスと対策(未定義変数・比較式の誤り)
Thymeleafでnull判定を行うとき、初心者が特によくつまずくのが「変数の未定義」や「比較式の書き方ミス」です。これらのミスは画面エラーや思わぬ表示不具合の原因となります。ここでは、代表的なミスとその対策を一つずつ丁寧に見ていきましょう。
まずありがちなのが、th:if="${user.name != null}"のように、オブジェクトが存在しない状態で直接プロパティにアクセスしてしまうケースです。user自体がnullであれば、この記述はエラーになります。
正しい方法は、必ず上位オブジェクトのnull判定を先に行うことです。つまり、次のように書きます。
<div th:if="${user != null and user.name != null}">
<p th:text="${user.name}"></p>
</div>
このように条件を分けて安全にアクセスすることで、Thymeleaf nullチェックの基本ルールを守れます。また、比較演算子の書き方にも注意が必要です。Thymeleafでは==ではなくeqを使う場合もあります。Javaに似ていますが、テンプレート内の式言語である点を意識しておきましょう。
次のように書くと、文字列の比較も安全に行えます。
<span th:if="${user.status eq 'ACTIVE'}">アクティブです</span>
一方で、==を使用すると、期待通りに動かない場合もあるため注意が必要です。特にnullとの比較は誤動作しやすく、結果が予想と異なることがあります。そのため、Thymeleafでnull判定を行う際は常に!= nullやeqなどを正しく使うようにしましょう。
新人
「なるほど、Javaと同じように書くときもあるけど、テンプレートのルールがあるんですね。」
先輩
「そうだね。Thymeleafでは、式を評価する順番や文法が微妙に違うから、細かい部分を意識するとトラブルを防げるよ。」
8. テンプレート設計のベストプラクティス(nullを前提にした安全な記述)
Thymeleafでテンプレートを設計する際のポイントは、「常にnullを前提に設計すること」です。つまり、どの変数も存在しない可能性を考慮しておくことで、安全で再利用性の高いテンプレートを作ることができます。
たとえば、次のようにnullチェックを組み込んだ構造を基本にしておくと、どんなデータ状態でも安定して表示が行えます。
<div th:if="${user != null}">
<p th:text="'ユーザー名:' + ${user.name}"></p>
<p th:text="'メール:' + ${user.email}"></p>
</div>
<div th:unless="${user != null}">
<p>ユーザー情報が未登録です。</p>
</div>
テンプレート側では常に「存在する場合」と「存在しない場合」を明確に分けておくことが重要です。さらに、コントローラ側でnullを返す設計よりも、空オブジェクトや空リストを返すようにしておくと、テンプレートがよりシンプルになります。
また、Thymeleafには#objectsというユーティリティもあり、オブジェクトの存在をチェックする便利な方法があります。以下のように書くことで、読みやすい条件分岐が可能になります。
<div th:if="${#objects.nonNull(user)}">
<p th:text="${user.name}"></p>
</div>
<div th:unless="${#objects.nonNull(user)}">
<p>データが見つかりません。</p>
</div>
このように、テンプレートの設計段階からnullを想定することで、実際の開発現場で起こる「意図しない表示崩れ」や「例外エラー」を未然に防ぐことができます。
さらに、複数のテンプレートを共通化する場合も、nullチェックを統一しておくことでメンテナンス性が上がります。プロジェクト全体の品質を維持するうえで非常に大切な考え方です。
新人
「なるほど。最初からnullを想定して書けば、あとで修正する手間が減るんですね!」
先輩
「その通り。エラーを出さない設計を心がけるのが、Thymeleaf nullチェックの基本だよ。」
9. Spring Controllerとの連携例(@ControllerとHTMLテンプレートの実装)
ここまで学んだ内容を踏まえて、Springの@ControllerとThymeleafテンプレートを組み合わせた具体的な実装例を紹介します。pleiades+Gradle環境で動作することを前提にしています。
まず、ユーザー情報を返すコントローラのサンプルです。データがnullの場合と存在する場合の両方を想定しています。
@Controller
public class ProfileController {
@GetMapping("/profile")
public String profile(Model model) {
User user = getUserData(); // データが存在しない場合はnullを返す
model.addAttribute("user", user);
return "profile";
}
private User getUserData() {
// 実際の処理ではデータベースから取得する想定
return null;
}
}
このコントローラでは、getUserData()でnullを返す可能性があります。そのため、テンプレート側でnull判定を行うことが非常に重要です。次に、対応するThymeleafテンプレートを見てみましょう。
<div th:if="${user != null}">
<h3>プロフィール情報</h3>
<p th:text="'名前:' + ${user.name}"></p>
<p th:text="'メール:' + ${user.email}"></p>
</div>
<div th:unless="${user != null}">
<h3>データ未登録</h3>
<p>プロフィール情報が見つかりませんでした。</p>
</div>
この構成であれば、コントローラがnullを返しても安全にHTMLをレンダリングできます。Thymeleaf nullチェックを組み合わせることで、アプリケーションの安定性が大幅に向上します。
また、Spring Controller側であらかじめ空オブジェクトを渡しておく設計も有効です。その場合、テンプレートではnull判定ではなくプロパティの中身をチェックすることで、より自然な制御が可能になります。
@Controller
public class ProfileController {
@GetMapping("/profile-safe")
public String profileSafe(Model model) {
User user = new User(); // 空のオブジェクトを生成
user.setName(null);
model.addAttribute("user", user);
return "profile";
}
}
このように、Controller側でデータを安全に渡し、テンプレートではnull判定を行う設計が最も堅牢です。特にpleiades+Gradle環境で学習を進める初心者にとっては、エラーの少ない構成を身につけることが上達への近道となります。
Thymeleafのnullチェックは単なる条件分岐ではなく、画面設計全体の品質を左右する重要な技術です。正しく理解して使いこなせば、Spring MVCでの開発効率と安全性を両立できます。
新人
「コントローラとテンプレートの両方で意識するのが大事なんですね!」
先輩
「そうだよ。Thymeleaf null判定をマスターすれば、エラー知らずの画面開発ができるようになる。これが実践的なSpring Controller nullチェックの基本なんだ。」
まとめ
ここまで、Thymeleaf null判定の基本から応用、そしてSpring Boot環境での具体的な実装方法について詳しく解説してきました。Webアプリケーション開発において、データベースから取得した値が空(null)である可能性を考慮することは、システムの安定性を高めるために欠かせないステップです。特にJavaとSpring Frameworkを組み合わせた開発現場では、コントローラから渡されるデータが常に完璧であることを期待するのではなく、テンプレート側で「もしデータがなかったらどうするか」という守りの設計を行うことが重要になります。
Thymeleaf null判定のポイントを再確認
Thymeleafでnullチェックを行う際の主要なテクニックを整理しました。これらを適切に使い分けることで、ユーザーにとって親切なUIを提供し、開発者にとってはデバッグのしやすい堅牢なコードを書くことができます。
- th:if と th:unless の使い分け: 条件が真のときに表示するなら
th:if、偽のときに表示するならth:unlessを使います。これらをペアで使うことで、「データがある場合の表示」と「ない場合の代替表示」を明確に分離できます。 - 安全なプロパティアクセス:
${user.name}のように深い階層にアクセスする場合、user自体がnullだとエラー(Exception)が発生します。必ず親オブジェクトの存在を確認してから子要素にアクセスする癖をつけましょう。 - ユーティリティオブジェクトの活用: リストの空判定には
#lists.isEmpty()、文字列の判定には#strings.isEmpty()といった便利な機能が用意されています。これらを使うと、nullチェックだけでなく「中身が空っぽ」という状態も一括で判定できるため、非常に効率的です。 - 論理演算子による複数条件:
andやor、notを組み合わせることで、より複雑なビジネスロジックをテンプレート上で表現できます。ただし、複雑になりすぎる場合はコントローラ側で値を整理して渡すように調整しましょう。
実践的なサンプルプログラム:データの有無による表示切り替え
実際のプロジェクトでもよく使われる、複数のnull判定パターンを網羅したサンプルを紹介します。このコードを参考に、自分のプロジェクトに合わせてカスタマイズしてみてください。
<!-- 1. シンプルなオブジェクトのnull判定 -->
<div class="user-profile" th:if="${member != null}">
<p>会員名:<span th:text="${member.name}">名無し</span></p>
<p th:if="${member.email != null}" th:text="'連絡先:' + ${member.email}">メールアドレスなし</p>
</div>
<!-- 2. リストの存在チェックとループ処理 -->
<div class="notice-area">
<h3>お知らせ一覧</h3>
<ul th:if="${not #lists.isEmpty(noticeList)}">
<li th:each="notice : ${noticeList}" th:text="${notice.title}">お知らせタイトル</li>
</ul>
<!-- リストが空、またはnullの場合の表示 -->
<p th:unless="${not #lists.isEmpty(noticeList)}">現在、新しいお知らせはありません。</p>
</div>
<!-- 3. エルビス演算子による簡略表示(値がnullならデフォルト値を出す) -->
<div class="status-info">
<p>現在のステータス:<span th:text="${status} ?: '未設定'">デフォルト表示</span></p>
</div>
上記のコードでは、th:ifだけでなく、エルビス演算子(?:)を使った便利な書き方も紹介しました。これは、変数がnullの場合に右側に書いた値をデフォルトとして表示してくれる便利な機能です。一行で簡潔に書きたい場合に非常に重宝します。
SEOを意識したシステム開発の考え方
Webサイトの評価(SEO)という観点からも、エラー画面をユーザーに見せないことは非常に重要です。検索エンジンのクローラーがページを巡回した際に、nullが原因で500エラーを返してしまうと、サイトの信頼性が低下し、検索順位に悪影響を及ぼす可能性があります。
「データがないなら、ないなりの適切なHTMLを返す」という実装は、単なるプログラミングのテクニックではなく、ユーザー体験(UX)を向上させ、検索エンジンからも高く評価されるサイト作りの基本なのです。Thymeleafの柔軟な条件分岐機能を使いこなし、どんな状況でも正しくレンダリングされるページを目指しましょう。
生徒
「先生、ありがとうございました!Thymeleafのnull判定をしっかり学んだおかげで、画面にエラーが出る恐怖がなくなりました。特にリストの判定方法(#lists.isEmpty)は、実際の業務でもすぐに使えそうです!」
先生
「それは良かった!プログラミングは『正常系』だけでなく、データがないといった『異常系』や『境界値』をどう扱うかが腕の見せ所なんだ。ThymeleafはHTMLの形を崩さずにそういった制御ができるのがいいよね。」
生徒
「確かに。今回学んだth:ifとth:unlessを使い分けることで、コードがとても読みやすくなりました。最初はJavaのif文と混同してしまいそうでしたが、SpEL式の書き方にも慣れてきました。」
先生
「その調子だね。あともう一歩ステップアップするなら、コントローラ側でOptionalを使ってみたり、デフォルト値を設定してからモデルに渡す工夫も考えてみるといい。フロント(Thymeleaf)とバックエンド(Spring)の両面でnull対策ができるようになれば、一人前のエンジニアだよ。」
生徒
「はい!どんなデータが来ても壊れない、ユーザーに優しい画面を作れるように頑張ります。次は共通テンプレートの中でのnull判定についても勉強してみたいです!」
先生
「いいね、その意欲があればどんどん上達するよ。困ったときはいつでも相談してね。一緒に高品質なシステムを作り上げていこう!」