サーブレット&JSPの基本|JSTLの基本と使い方

EL式だけでは書きにくい分岐と繰り返しを、JSTLでタグ化する。ひとこと広場のJSPからJavaコードをなくして、画面をもっと読みやすくしよう

前回は、EL式を使ってJSPを簡潔にする方法を学習しました。

EL式を使うと、スコープに保存されたJavaBeansのプロパティを、短い記述で画面に表示できます。

たとえば、セッションスコープにloginUserという属性名でUserインスタンスが保存されている場合、利用者名は次のように表示できます。

${loginUser.name}

従来のように、Userクラスをimportし、session.getAttributeで取得し、User型にキャストし、getNameメソッドを呼び出す必要がありません。

このように、EL式はJSPをすっきり書くためにとても便利です。

ただし、EL式だけでは、条件分岐や繰り返しの処理を書くには限界があります。

たとえば、ひとこと広場のloginResult.jspでは、ログイン成功時と失敗時で表示内容を切り替える必要があります。

また、main.jspでは、messageListに入っている投稿を先頭から順番に表示する必要があります。

これまでのJSPでは、このような分岐や繰り返しにスクリプトレットを使っていました。

しかし、JSPの中にJavaのif文やfor文が増えると、画面表示のためのHTMLとJavaの処理が混ざり、読みづらくなってしまいます。

そこで使うのが、JSTLです。

JSTLを使うと、条件分岐や繰り返しをタグとして書けます。

つまり、JSPの中にJavaのコードを書かなくても、ログイン成功時と失敗時の分岐や、投稿一覧の繰り返し表示を表現できます。

この記事では、JSTLの基本、taglibディレクティブの書き方、Coreタグライブラリの代表的なタグ、そしてひとこと広場のloginResult.jspとmain.jspをEL式とJSTLで書き直す方法を学習します。

JSTLとは

JSTLは、Jakarta Standard Tag Libraryの略です。

JSPでよく使う処理を、タグとして利用できるようにまとめたタグライブラリです。

JSPには、jsp:includeやjsp:forwardのような標準アクションタグが用意されています。

これらはJSPに最初から用意されているタグです。

一方、JSTLは、条件分岐、繰り返し、変数出力など、JSPでよく使う処理をカスタムタグとしてまとめたライブラリです。

JSTLでできること

処理内容
変数の出力値を安全に画面へ表示する
条件分岐条件に応じて表示内容を切り替える
多分岐複数の条件を順番に判定する
繰り返しリストや配列の内容を順番に表示する
リダイレクト指定したURLへ移動する

JSTLを使うと、Javaのスクリプトレットを書かずに、タグ形式で分岐や繰り返しを表現できます。

そのため、JSPをHTMLに近い見た目で保ちやすくなります。

カスタムタグとタグライブラリ

JSPでは、あらかじめ用意されている標準アクションタグのほかに、独自のタグを作成することもできます。

このようなタグをカスタムタグと呼びます。

作成したカスタムタグをまとめたものが、タグライブラリです。

JSTLは、よく使われるカスタムタグをまとめた代表的なタグライブラリです。

標準アクションタグとカスタムタグ

種類内容
標準アクションタグjsp:include、jsp:forwardJSPに標準で用意されているアクションタグ
カスタムタグc:if、c:forEach、c:outタグライブラリとして提供されるタグ
JSTLCore、I18N、Functionsなどよく使うカスタムタグをまとめたライブラリ

カスタムタグは自分で作ることもできますが、実際の開発では、まず既存のタグライブラリを使う場面が多くなります。

JSTLはその代表であり、JSPを簡潔にするうえでとても重要です。

図1:EL式とJSTLでJSPからJavaコードを減らす

この図から分かること

EL式は、スコープに保存されたインスタンスやJavaBeansのプロパティを簡潔に取得するために使います。

JSTLは、条件分岐や繰り返しなど、EL式だけでは書きにくい処理をタグで表現するために使います。

この2つを組み合わせると、JSPからJavaのスクリプトレットやスクリプト式を大きく減らせます。

ひとこと広場のloginResult.jspやmain.jspも、EL式とJSTLを使うことで、Javaコードをほとんど書かずに同じ画面表示を実現できます。

JSTLを使うための準備

JSTLは、JSPに最初から何もしなくても使えるものではありません。

JSTLを使うには、必要なJARファイルをダウンロードし、動的Webプロジェクトに配置します。

ここでは、Jakarta版のJSTLを利用します。

必要なJARファイル

種類役割
JSTL APIJSTLのインタフェースを提供する
JSTL 実装JSTLの実際の処理を提供する

JSTLを使うには、APIと実装の両方が必要です。

どちらか一方だけでは、JSPでJSTLタグを正しく使えません。

JSTL APIをダウンロードする

まず、JSTL APIのJARファイルをダウンロードします。

Maven RepositoryのJSTL APIのページにアクセスし、Filesのjarをクリックしてダウンロードします。

https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api/3.0.2

今回の範囲では、次のJSTL APIを使います。

jakarta.servlet.jsp.jstl-api 3.0.2

JSTL APIは、JSTLの機能を使うためのインタフェースを提供します。

ただし、APIだけでは実際の処理は動きません。

次に、JSTLの実装もダウンロードします。

JSTLの実装をダウンロードする

次に、JSTLの実装のJARファイルをダウンロードします。

Maven RepositoryのJSTL実装のページにアクセスし、Filesのjarをクリックしてダウンロードします。

https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl/3.0.1

今回の範囲では、次のJSTL実装を使います。

jakarta.servlet.jsp.jstl 3.0.1

この実装JARがあることで、JSTLタグの処理が実際に動作します。

JSTL APIとJSTL実装の2つを用意したら、次にプロジェクトへ配置します。

JARファイルをWEB-INF/libに配置する

ダウンロードした2つのJARファイルは、動的WebプロジェクトstudyのWEB-INF/libフォルダに配置します。

配置場所は次の通りです。

src/main/webapp/WEB-INF/lib

このlibフォルダにJARファイルをコピーすると、WebアプリケーションからJSTLを利用できるようになります。

保存した2つのJARファイルを Eclipse の動的Webプロジェクト内の src/main/webapp/WEB-INF/lib フォルダにドラッグアンドドロップします。

下図のダイアログが表示されたら「ファイルをコピー」を選択して「OK」をクリックします。

配置時の注意

項目内容
配置先src/main/webapp/WEB-INF/lib
配置するJARJSTL APIとJSTL実装の2つ
注意点WEB-INF直下ではなく、WEB-INF/libに配置する
Eclipseでの操作ドラッグアンドドロップ時はファイルをコピーを選ぶ

WEB-INFに直接置くのではなく、WEB-INF/libに置く点に注意しましょう。

JARファイルを配置したら、Eclipse上でsrc/main/webapp/WEB-INF/libに2つのJARファイルが入っていることを確認します。

JSTLのタグライブラリ

JSTLは、複数のタグライブラリで構成されています。

それぞれ役割が異なります。

JSTLのタグライブラリ一覧

タグライブラリ内容
Core変数、条件分岐、繰り返しなどの基本的な処理に関するタグ
I18N数値や日付のフォーマット、国際化対応に関するタグ
Databaseデータベース操作に関するタグ
XMLXML操作に関するタグ
Functionsコレクションや文字列を操作する関数

この中で、ServletとJSPの入門で特によく使うのがCoreタグライブラリです。

Coreタグライブラリには、変数出力、条件分岐、繰り返しなど、JSPでよく使う基本的なタグが含まれています。

ひとこと広場のJSPを書き直すときも、Coreタグライブラリを使います。

taglibディレクティブとは

JSPでJSTLを使うには、taglibディレクティブを書きます。

taglibディレクティブは、このJSPファイルでどのタグライブラリを使うのかを指定するための記述です。

基本形は次の通りです。

<%@ taglib prefix="接頭辞" uri="タグライブラリのURI" %>

prefix属性には、JSP内でタグを書くときの接頭辞を指定します。

uri属性には、使用するタグライブラリのURIを指定します。

Coreタグライブラリを使う場合は、次のように書きます。

<%@ taglib prefix="c" uri="jakarta.tags.core" %>

この指定により、JSP内でc:out、c:if、c:choose、c:forEachなどのタグを使えるようになります。

prefix属性とuri属性

taglibディレクティブでは、prefix属性とuri属性を指定します。

taglibディレクティブの属性

属性内容
prefixJSP内でタグを書くときの接頭辞
uri使用するタグライブラリを識別するURI

prefix属性は、タグライブラリに付ける短い名前のようなものです。

Coreタグライブラリでは、一般的にcを使います。

そのため、Coreタグライブラリのoutタグは、c:outと書きます。

I18Nタグライブラリではfmt、Functionsタグライブラリではfnがよく使われます。

JSTLタグライブラリのtaglibディレクティブ

タグライブラリtaglibディレクティブ
Core<%@ taglib prefix="c" uri="jakarta.tags.core" %>
I18N<%@ taglib prefix="fmt" uri="jakarta.tags.fmt" %>
Database<%@ taglib prefix="sql" uri="jakarta.tags.sql" %>
XML<%@ taglib prefix="x" uri="jakarta.tags.xml" %>
Functions<%@ taglib prefix="fn" uri="jakarta.tags.functions" %>

今回の記事では、Coreタグライブラリを使うため、JSPの先頭付近に次の1行を追加します。

<%@ taglib prefix="c" uri="jakarta.tags.core" %>

図2:taglibディレクティブでCoreタグライブラリを使えるようにする

この図から分かること

JSTLを使うには、まず必要なJARファイルをWEB-INF/libに配置します。

そのうえで、JSPファイルにtaglibディレクティブを書き、使用するタグライブラリを指定します。

Coreタグライブラリを使う場合は、prefixにc、uriにjakarta.tags.coreを指定します。

これにより、JSP内でc:out、c:if、c:choose、c:forEachなどのCoreタグを利用できるようになります。

Coreタグライブラリでよく使うタグ

Coreタグライブラリには、JSPでよく使う基本的な処理を行うタグが用意されています。

Coreタグライブラリの主なタグ

タグの機能タグ内容
変数設定c:set変数を設定する
変数削除c:remove変数を削除する
変数出力c:out値を出力する
2分岐c:if条件がtrueのときだけ処理する
多分岐c:choose、c:when、c:otherwise複数条件で表示を切り替える
繰り返しc:forEachリストや配列などを繰り返し処理する
リダイレクトc:redirect指定したURLへリダイレクトする

今回のひとこと広場では、主に次のタグを使います。

タグ使う場面
c:out利用者名、エラーメッセージ、投稿者名、投稿内容を出力する
c:chooseログイン成功と失敗を分岐する
c:whenログイン成功時の表示を書く
c:otherwiseログイン失敗時の表示を書く
c:ifエラーメッセージがあるときだけ表示する
c:forEach投稿一覧を繰り返し表示する

これらを使うことで、ひとこと広場のJSPからJavaのスクリプトレットをなくせます。

カスタムタグの基本文法

JSTLのタグは、次のような形式で使います。

<接頭辞:タグ名 属性名="値">内容</接頭辞:タグ名>

また、内容を持たないタグは、次のように書けます。

<接頭辞:タグ名 属性名="値" />

Coreタグライブラリでは、taglibディレクティブでprefixにcを指定することが多いため、次のようなタグになります。

書き方内容
<c:out value="${loginUser.name}" />loginUserのnameを出力する
<c:if test="${not empty errorMsg}">errorMsgが空でないときだけ処理する
<c:forEach var="message" items="${messageList}">messageListを順番に取り出す

接頭辞は、taglibディレクティブのprefix属性で指定した値です。

Coreタグライブラリにcを指定した場合、c:outやc:forEachのように書きます。

c:outで値を安全に出力する

c:outは、値を画面に出力するためのタグです。

基本形は次の通りです。

<c:out value="出力する値" />

value属性には、EL式を指定できます。

たとえば、ログイン中の利用者名を出力する場合は、次のように書きます。

<c:out value="${loginUser.name}" />

EL式だけでも、${loginUser.name}のように値を出力できます。

しかし、ユーザーが入力した内容を表示する場合は、c:outを使うほうが安全です。

c:outを使う理由

項目内容
値を出力できるEL式で取得した値を画面に表示する
エスケープできるHTMLとして意味を持つ記号を無害化して出力する
XSS対策につながるユーザー入力をそのままHTMLとして解釈させにくくする

たとえば、投稿内容に<や>が含まれている場合、そのまま出力するとHTMLタグとして解釈される可能性があります。

c:outは、そのような特殊な記号をエスケープして出力します。

ひとこと広場では、利用者が投稿したtextを画面に表示するため、c:outを使うのが適しています。

c:ifで条件に合うときだけ表示する

c:ifは、条件がtrueのときだけ中身を実行するタグです。

基本形は次の通りです。

<c:if test="条件式">
条件式がtrueなら実行される処理
</c:if>

test属性には、EL式を使った条件を書けます。

たとえば、エラーメッセージがあるときだけ表示したい場合は、次のように書きます。

<c:if test="${not empty errorMsg}">
<c:out value="${errorMsg}" />
</c:if>

errorMsgが存在し、空でなければ、中のpタグが出力されます。

errorMsgがない場合は、何も表示されません。

c:ifが向いている場面

場面
メッセージがあるときだけ表示するerrorMsgがある場合だけ表示する
条件を満たした場合だけ案内を出す投稿数が0のときだけ案内を出す
特定状態のときだけリンクを表示する管理者のときだけ管理画面リンクを表示する

c:ifは、シンプルな条件分岐に向いています。

ただし、falseの場合にも別の処理をしたいときは、c:chooseを使います。

c:chooseで成功と失敗を分岐する

c:chooseは、Javaのif、else if、elseのような多分岐を表現するタグです。

c:chooseの中に、c:whenとc:otherwiseを書きます。

基本形は次の通りです。

<c:choose>
<c:when test="条件式">
条件式がtrueなら実行される処理
</c:when>
<c:otherwise>
すべての条件がfalseなら実行される処理
</c:otherwise>
</c:choose>

c:whenは複数書けます。

c:otherwiseは、どのc:whenにも当てはまらなかった場合の処理です。

ひとこと広場のloginResult.jspでは、ログイン成功時と失敗時で表示内容を切り替えます。

ログイン成功時は、Login.javaでセッションスコープにloginUserが保存されています。

そのため、JSTLでは次のように判定できます。

<c:when test="${not empty loginUser}">

loginUserが空でなければログイン成功、空であればログイン失敗として表示を分けられます。

c:forEachで繰り返し表示する

c:forEachは、繰り返し処理を行うタグです。

通常のfor文のように、回数を指定して繰り返すこともできます。

基本形は次の通りです。

<c:forEach var="カウンタ変数" begin="最初の値"
end="最後の値" step="増加値">
繰り返し実行する処理
</c:forEach>

たとえば、0から9まで表示する場合は、次のように書きます。

<c:forEach var="i" begin="0" end="9" step="1">
<c:out value="${i}" />
</c:forEach>

var属性で指定したiは、ページスコープに保存されます。

そのため、タグの中では${i}として参照できます。

通常のfor文との対応

JSTLJavaのイメージ
var="i"int i
begin="0"i = 0
end="9"i <= 9
step="1"i++

end属性に指定した値まで繰り返す点に注意しましょう。

beginが0、endが9、stepが1の場合、0から9までの10回繰り返します。

リストをc:forEachで表示する

c:forEachは、拡張for文のようにも使えます。

リストや配列などの集合をitems属性に指定すると、その中の要素を先頭から順に取り出せます。

基本形は次の通りです。

<c:forEach var="変数名" items="インスタンスの集合">
繰り返し実行する処理
</c:forEach>

items属性には、EL式でリストを指定します。

ひとこと広場では、投稿一覧がmessageListという属性名でアプリケーションスコープに保存されています。

そのため、main.jspでは次のように書けます。

<c:forEach var="message" items="${messageList}">

<c:out value="${message.userName}" />:
<c:out value="${message.text}" />

</c:forEach>

この書き方により、messageListに入っているShortMessageインスタンスを先頭から順番に取り出し、投稿者名と投稿内容を表示できます。

c:forEachで投稿一覧を表示する流れ

順番内容
1items属性でmessageListを指定する
2messageListの先頭からShortMessageを1つ取り出す
3var属性で指定したmessageに代入する
4message.userNameとmessage.textをc:outで出力する
5リストの要素数だけ繰り返す

Javaの拡張for文で書くと、for (ShortMessage message : messageList)のようなイメージです。

JSTLを使うと、これをJSP上でタグとして表現できます。

図3:c:choose、c:if、c:forEachでひとこと広場のJSPを改良する

この図から分かること

ひとこと広場では、ログイン結果画面とメイン画面でJSTLが役立ちます。

loginResult.jspでは、c:choose、c:when、c:otherwiseを使うことで、ログイン成功時と失敗時の表示をタグで分けられます。

main.jspでは、c:ifでエラーメッセージがあるときだけ表示し、c:forEachでmessageListに入っている投稿を繰り返し表示できます。

また、利用者名や投稿内容の出力にはc:outを使うことで、安全に値を表示できます。

ひとこと広場のloginResult.jspをJSTLで改良する

ここからは、ここまで作成してきたひとこと広場のJSPを、EL式とJSTLを使って書き直します。

まずは、ログイン結果画面のloginResult.jspです。

これまでのloginResult.jspでは、セッションスコープからloginUserを取得するためにスクリプトレットを使っていました。

JSTL版では、Javaコードを書かずに、c:chooseでログイン成功と失敗を分岐します。

ログイン成功の判定には、EL式のnot emptyを使います。

loginUserが存在すればログイン成功、存在しなければログイン失敗として表示します。

ひとこと広場のログイン結果画面の例

ファイル名: loginResult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ひとこと広場</title>
</head>
<body>
<h1>ひとこと広場ログイン</h1>

<c:choose>
    <c:when test="${not empty loginUser}">
        <p>ログインに成功しました</p>
        <p>ようこそ<c:out value="${loginUser.name}" />さん</p>
        <a href="Main">ひとこと投稿・閲覧へ</a>
    </c:when>
    <c:otherwise>
        <p>ログインに失敗しました</p>
        <a href="index.jsp">トップへ</a>
    </c:otherwise>
</c:choose>

</body>
</html>

このJSPは、src/main/webapp/WEB-INF/jspディレクトリに配置します。

JSTLを使うため、pageディレクティブの下にtaglibディレクティブを追加しています。

<%@ taglib prefix="c" uri="jakarta.tags.core" %>

これにより、c:choose、c:when、c:otherwise、c:outを使えるようになります。

loginResult.jspの改良ポイント

このloginResult.jspでは、Javaのスクリプトレットを使っていません。

変更された考え方

従来の処理JSTL版
session.getAttributeでloginUserを取得するEL式でloginUserを参照する
if文でloginUser != nullを判定するc:when test="${not empty loginUser}"で判定する
loginUser.getNameで利用者名を取得するc:out value="${loginUser.name}"で出力する
スクリプトレットで分岐するc:chooseで分岐する

Login.javaでログイン成功時にloginUserをセッションスコープへ保存しているため、JSP側では${loginUser}として参照できます。

EL式は、ページスコープ、リクエストスコープ、セッションスコープ、アプリケーションスコープの順に属性名を探します。

loginUserはセッションスコープに保存されているため、${loginUser.name}で利用者名を取得できます。

c:chooseでログイン結果を分ける

loginResult.jspでは、次の構成でログイン結果を分けています。

<c:choose>
<c:when test="${not empty loginUser}">
ログイン成功時の表示
</c:when>
<c:otherwise>
ログイン失敗時の表示
</c:otherwise>
</c:choose>

分岐の内容

条件表示内容
loginUserが空でないログインに成功しました、ようこそ利用者名さん、ひとこと投稿・閲覧へ
loginUserが空ログインに失敗しました、トップへ

このように、JSTLを使うと、if文を書かずにタグで分岐を表現できます。

画面表示の中にJavaコードが入り込まないため、JSPが読みやすくなります。

ひとこと広場のmain.jspをJSTLで改良する

次に、ひとこと広場のメイン画面であるmain.jspを改良します。

main.jspでは、次の処理を行います。

main.jspで行う処理

処理JSTLで使うタグ
ログイン中の利用者名を表示するc:out
エラーメッセージがあるときだけ表示するc:if
投稿一覧を繰り返し表示するc:forEach
投稿者名と投稿内容を安全に出力するc:out

これまでのmain.jspでは、User、ShortMessage、Listをimportし、session.getAttributeやapplication.getAttributeを使ってインスタンスを取得し、拡張for文でmessageListを表示していました。

JSTL版では、これらのJavaコードをJSPに書かず、EL式とJSTLタグで表現します。

ひとこと広場のメイン画面の例

ファイル名: main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ひとこと広場</title>
</head>
<body>
<h1>ひとこと広場メイン</h1>

<p>
<c:out value="${loginUser.name}" />さん、ログイン中
<a href="Logout">ログアウト</a>
</p>

<p><a href="Main">更新</a></p>

<form action="Main" method="post">
<input type="text" name="text">
<input type="submit" value="投稿">
</form>

<c:if test="${not empty errorMsg}">
    <p><c:out value="${errorMsg}" /></p>
</c:if>

<c:forEach var="message" items="${messageList}">
    <p>
        <c:out value="${message.userName}" />:
        <c:out value="${message.text}" />
    </p>
</c:forEach>

</body>
</html>

このJSPも、src/main/webapp/WEB-INF/jspディレクトリに配置します。

JSTLを使うために、taglibディレクティブを追加しています。

このmain.jspでは、Javaのスクリプトレットを使っていません。

画面表示に必要な値はEL式で取得し、出力や分岐、繰り返しはJSTLタグで行っています。

main.jspの改良ポイント

JSTL版のmain.jspでは、Javaのimportが不要になっています。

また、session.getAttributeやapplication.getAttributeをJSP内に書いていません。

従来のmain.jspとJSTL版の違い

従来の処理JSTL版
User、ShortMessage、Listをimportするimportしない
session.getAttributeでloginUserを取得する${loginUser.name}で参照する
application.getAttributeでmessageListを取得する${messageList}で参照する
request.getAttributeでerrorMsgを取得する${errorMsg}で参照する
if文でerrorMsgを判定するc:ifで判定する
拡張for文でmessageListを繰り返すc:forEachで繰り返す
スクリプト式で値を出力するc:outで出力する

loginUserはセッションスコープ、messageListはアプリケーションスコープ、errorMsgはリクエストスコープに保存されています。

EL式はこれらのスコープから属性名を探してくれるため、JSP側ではシンプルに書けます。

c:ifでエラーメッセージを表示する

main.jspでは、空の投稿が送信された場合だけエラーメッセージを表示します。

Main.javaでは、空投稿時にerrorMsgという属性名でリクエストスコープにメッセージを保存しています。

JSTL版では、次のように書きます。

<c:if test="${not empty errorMsg}">
<c:out value="${errorMsg}" />
</c:if>

c:ifの動き

errorMsgの状態表示
errorMsgがあるひとことが入力されていませんを表示する
errorMsgがない何も表示しない

not emptyは、EL式で使える便利な判定です。

errorMsgが存在し、空でない場合だけtrueになります。

c:forEachで投稿一覧を表示する

ひとこと広場の投稿一覧は、messageListに保存されています。

messageListには、ShortMessageインスタンスが複数入っています。

JSTL版では、次のようにc:forEachを使って表示します。

<c:forEach var="message" items="${messageList}">

<c:out value="${message.userName}" />:
<c:out value="${message.text}" />

</c:forEach>

c:forEachの属性

属性内容
var取り出した要素を入れる変数名
items繰り返し対象のリストや配列

itemsに${messageList}を指定すると、messageListの要素が先頭から順に取り出されます。

取り出されたShortMessageインスタンスは、varで指定したmessageに入ります。

そのため、ループ内では${message.userName}や${message.text}でプロパティを取得できます。

c:outで投稿内容を表示する理由

投稿者名や投稿内容は、利用者が入力した値です。

そのため、画面に表示するときは、できるだけc:outを使うのが安全です。

たとえば、投稿内容にHTMLタグのような文字列が入力された場合、そのまま出力すると、ブラウザがHTMLとして解釈してしまう可能性があります。

c:outを使うと、HTMLとして特別な意味を持つ記号をエスケープして出力できます。

ひとこと広場でc:outを使う場所

表示内容書き方
ログイン中の利用者名<c:out value="${loginUser.name}" />
エラーメッセージ<c:out value="${errorMsg}" />
投稿者名<c:out value="${message.userName}" />
投稿内容<c:out value="${message.text}" />

特に投稿内容は、利用者が自由に入力できる値です。

安全に表示するためにも、EL式だけで出力するより、c:outを使う意識を持っておくとよいです。

動作確認の前に確認すること

JSTL版のJSPを動かす前に、JSTLのJARファイルが正しく配置されているか確認します。

確認ポイント

確認すること内容
JARファイルJSTL APIとJSTL実装の2つがあるか
配置場所src/main/webapp/WEB-INF/libに入っているか
taglibディレクティブJSPにCoreタグライブラリの指定があるか
URIjakarta.tags.coreになっているか
prefixcになっているか

JARファイルを配置し忘れると、JSPでc:outやc:forEachを使ったときにエラーになります。

また、taglibディレクティブのuriを間違えると、JSTLタグが認識されません。

ひとこと広場で動作確認する

JSPを書き換えたら、ひとこと広場をトップ画面から実行します。

プロジェクト名はstudyなので、URLは次のようになります。

http://localhost:8080/Hiroba/

動作確認の手順

手順内容
1動的プロジェクト「Hiroba」へ JSTLのJARファイルをsrc/main/webapp/WEB-INF/libに配置する
2loginResult.jspをEL式とJSTL版に書き換える
3main.jspをEL式とJSTL版に書き換える
4studyをTomcat11_Java25に追加する
5サーバを起動または再起動する
6ブラウザでhttp://localhost:8080/Hiroba/へアクセスする
7任意の利用者名とパスワード1234でログインする
8ログイン結果画面が正しく表示されることを確認する
9ひとこと投稿・閲覧へをクリックする
10メイン画面が正しく表示されることを確認する
11ひとことを投稿し、一覧に表示されることを確認する
12空投稿でエラーメッセージが表示されることを確認する

※注意:動的プロジェクトの「Hiroba」のsrc/main/webapp/WEB-INF/lib に JSTL APIとJSTL 2つを配置します。

JSPの書き方は変わりましたが、実行結果はこれまでと同じです。

大切なのは、画面の動きは変えずに、JSPの中からJavaコードを減らしている点です。

ブラウザの表示例

EL式とアクションタグの関係

EL式は、スコープに保存されたインスタンスや、そのプロパティを簡潔に参照するための書き方です。

JSTLのタグは、EL式を属性値として受け取ることができます。

たとえば、c:outのvalue属性にEL式を書けば、その値を出力できます。

<c:out value="${loginUser.name}" />

c:ifのtest属性にEL式を書けば、その結果がtrueかfalseかで表示を分岐できます。

<c:if test="${not empty errorMsg}">

c:forEachのitems属性にEL式を書けば、スコープに保存されたリストを繰り返し対象にできます。

<c:forEach var="message" items="${messageList}">

このように、EL式とJSTLは組み合わせて使うと力を発揮します。

EL式とJSTLの役割分担

技術役割
EL式スコープの値やJavaBeansのプロパティを取得する
JSTL分岐、繰り返し、出力などをタグで表現する
HTML画面の構造を作る

EL式で値を取り出し、JSTLで条件分岐や繰り返しを行い、HTMLで画面として表示する。

この流れを意識すると、JSPをきれいに整理しやすくなります。

JSPからJavaコードをなくすメリット

EL式とJSTLを使うと、JSPの中からJavaのスクリプトレットを減らせます。

これは、単にコードが短くなるだけではありません。

Webアプリケーションの開発では、画面の見た目をWebデザイナーが調整し、サーブレットやモデルの処理をJava開発者が担当することがあります。

JSPにJavaコードが多いと、画面修正のときにJavaの処理まで誤って変更してしまう可能性があります。

一方、JSPがHTMLタグ、JSTLタグ、EL式を中心に書かれていれば、画面構造を把握しやすくなります。

JSPをタグ中心にするメリット

メリット内容
読みやすくなるHTMLに近い形で画面を確認できる
分業しやすくなる画面担当者が編集しやすい
Javaコードの誤編集を減らせるスクリプトレットを触る機会を減らせる
表示処理が整理される値の取得はEL式、分岐や繰り返しはJSTLに分けられる
保守しやすくなる画面表示の意図が分かりやすくなる

ひとこと広場のJSPも、EL式とJSTLを使うことで、Javaコードを書かずに同じ表示を実現できました。

JSTLを使うときに意識したいこと

JSTLを使うと、JSPをかなり読みやすくできます。

ただし、JSTLの役割は、あくまで画面表示に必要な分岐や繰り返しをタグで表現することです。

複雑な業務処理や計算処理をJSPに詰め込むのは避けましょう。

意識したいポイント

ポイント内容
JSTLは画面表示の補助に使う複雑な処理はサーブレットやモデルに任せる
ユーザー入力はc:outで出力するエスケープされるため安全性が高い
taglibディレクティブを忘れないJSTLタグを使うJSPには必要
JARファイルの配置を確認するWEB-INF/libにAPIと実装を配置する
EL式と組み合わせる値の取得はEL式、分岐や繰り返しはJSTLで行う

JSTLは、EL式と組み合わせることで、JSPをタグ中心の読みやすいファイルにできます。

ひとこと広場のloginResult.jspでは、c:chooseでログイン成功と失敗を分岐しました。

main.jspでは、c:ifでエラーメッセージを表示し、c:forEachで投稿一覧を繰り返し表示しました。

これにより、画面の動きはそのままに、JSPからJavaのスクリプトレットをなくすことができました。