Java入門 / Web入門

【Java Web入門 #9】標準タグライブラリ(JSTL)の利用(1)|利用手順とcoreライブラリ

2025.02.07

JSPの動的表示のために利用されるものとして、前回までスクリプトレット、式といったJSPの要素、標準アクション、EL式についてご紹介しました。当記事では、JSPの動的表現とシンプルな表記のために欠かせないJSPの標準タグライブラリについて、利用手順および基本となるタグライブラリである core タグライブラリの利用方法について解説します。

◆Java Web入門の過去記事はこちら
◆Java入門 記事一覧はこちら

標準タグライブラリ(JSTL)とは

JSPの標準タグライブラリ(JSTL)とは、よく利用される標準的な機能を、JSP上でタグとして簡単に記述できるようにまとめたものです。JSTLを利用することでスクリプトレットなどの記述を減らすことができ、簡潔で読みやすいJSPにすることができます。

「JSTL」は英名の略称で、標準タグライブラリは以前「JSP Standard Tag Library」という名称でしたが、現在は「Jakarta Standard Tag Library」という名称になっています。

参考:Jakarta Standard Tag Library(公式サイト・英語)

JSTLの利用準備

JSTLを利用するためには、タグのクラスファイルを格納したjarファイルをダウンロードし、Webアプリケーションに配置します。(Mavenを利用する方法もありますが、できる方は当記事を読まなくてもJSTLを使いこなせると思いますので、ここでは割愛します)

jarファイルのダウンロード

JSTLを利用するために、APIと実装(implement)の2つのjarファイルをダウンロードします。Jakarta EE 10 以降のバージョンでは、JSTL 3.0を利用します。(2025年2月現在)

jarファイルは、以下のサイトからダウンロードできます。各リンク先画面内にあるjarファイルのダウンロードリンク(画像参照)をクリックして、ファイルをダウンロードしてください。

・Jakarta Standard Tag Library API
 https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api/3.0.2
・Jakarta Standard Tag Library Implementation
 https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl/3.0.1

※ Jakarta EE 9 以前のバージョンを利用する場合はこちらを参照

Jakarta EE 9 を利用する場合はJSTL 2.0、Jakarta EE 8および Java EE を利用する際はJSTL 1.2系のjarファイルをダウンロードしてお使いください。Jakarta EE 8 以前はクラスのパッケージ名が異なります。

Jakarta EE向け
・Jakarta Standard Tag Library API 
 https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api
・Jakarta Standard Tag Library Implementation
 https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl

Java EE向け
・JavaServer Pages(TM) Standard Tag Library
 https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api
・JavaServer Pages (TM) TagLib Implementation
 https://mvnrepository.com/artifact/org.glassfish.web/jstl-impl

jarファイルの配置

ダウンロードしたjarファイルは、Webアプリケーション内の「/WEB-INF/lib」ディレクトリの中に配置します。ダウンロードしたファイルをコピー&ペーストや、Eclipseであれば「WEB-INF/lib」ディレクトリにjarファイルをドラッグ&ドロップする(※)ことで配置できます。


※Ecipse上へファイルをドロップした際、ファイルをコピーするか、リンクするかの確認が表示されることがあります。どちらでも動作はしますが、誤って消すことなどが無いようコピーしておくことを推奨します。

JSTLの種類と書式

JSTLには、機能ごとにまとめられた以下の5つのタグライブラリが含まれています。

タグライブラリ名説明
core変数の設定や条件判定など最も基本的な機能を提供するタグ
i18n
(i8n-capable formatting)
国際化・多言語化に対応のためのロケールの指定や、日付、数値などの書式を提供するタグ
i18nとは、internationalization(国際化)のことを指す。
Functions分割や置換、文字数の取得など、文字列操作の機能を提供するタグ
SQL
(relational db access)
リレーショナルデータベースへのSQLアクセス機能を提供するタグ
XMLXML文書を操作する機能を提供するタグ

参考:Jakarta Standard Tag Library 3.0 Specification Document(公式サイト・英語)
参考:Jakarta Standard Tag Library 3.0 Tagdoc(公式サイト・英語)

JSTL Coreライブラリの利用

実際にJSP上でタグを利用する方法についてご説明します。ここでは、最も基本的な core タグライブラリについてご説明します。

書式

JSTLのタグを利用する場合、taglib ディレクティブにタグごとに定めされた uri と、prefix にタグのプレフィックスとして利用する名前を指定する必要があります。

タグライブラリ名prefixuri(JSTL 3.0)uri(JSTL 2.0以前)
corec:jakarta.tags.corehttp://java.sun.com/jsp/jstl/core
i18n
(i8n-capable formatting)
fmt:jakarta.tags.fmthttp://java.sun.com/jsp/jstl/fmt
Functionsfn:jakarta.tags.functionshttp://java.sun.com/jsp/jstl/functions
SQL
(relational db access)
sql:jakarta.tags.sqlhttp://java.sun.com/jsp/jstl/sql
XMLx:jakarta.tags.xmlhttp://java.sun.com/jsp/jstl/xml

uri は JSTL3.0 で各タグに指定する内容が変更となっています。また、プレフィックスは任意の名前を付けることも可能ですが、JSTLの各タグライブラリの利用時には、可読性のためにも通例で定められたプレフィックスを利用するのが良いでしょう。

・書式
 <%@ taglib uri="タグのURI" prefix="タグのプレフィックス" %>

JSTL3.0 の core タグライブラリを利用する場合は、以下のようにディレクティブを記述します。

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

変数・例外の処理

<c:set>変数を定義して指定のスコープに保持する。
<c:remove>変数を指定のスコープから取り除く。
<c:out>変数、式を出力する。
<c:catch>JSPで発生した例外をcatchする。

<c:set>

<c:set>タグは、変数の定義、または既存の変数への値の設定を行います。また、各スコープ内に保持されているJavaBeansやMap等のオブジェクトに対して値を設定することも可能です。

属性名必須説明
var※1新しく定義、または値を置き換える変数名を指定する。
target※1値の設定対象を持つJavaBeans、Map等のオブジェクトを指定する。
property※1targetと同時に指定し、値の設定対象であるプロパティ名・キー名を指定する。
value設定する値を指定する。
scope※2変数の保持先スコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
※1 変数に直接値を設定する場合は var の指定、JavaBeansやMap等のオブジェクトにプロパティ・キー名を指定して値を設定する場合は target + property の指定が必須。
※2 varの指定時のみscopeの指定が可能。

設定する値はvalue属性に指定するか、タグのボディ部のいずれかに設定します。(両方設定した場合は解析エラーとなります)

Java
<%-- varを指定 --%>
<c:set var="name" value="knovus" />
<c:set var="name">knovus</c:set>

<%-- targetとpropertyを指定 --%>
<jsp:useBean id="userinfo" class="site.knovus.beans.UserInfo" scope="session"/>
<c:set target="${userinfo}" property="age" value="21" />
<c:set target="${userinfo}" property="age" >21</c:set>


<c:set>タグでは、scope を指定しなかった場合はページスコープ内のオブジェクトが対象です。ページスコープ以外を対象とする場合はscopeの指定が必要となります。但し、上記サンプルコードの「target」のように、オブジェクトの指定をEL式で行う場合は、<c:set>タグでscopeを指定しなくても、EL式の動作により全スコープから検索されます。

<c:remove>

<c:remove>タグは、各スコープ内に保持されたオブジェクトを除去します。これは各スコープのremoveAttributeメソッドと同じ動作です。

属性名必須説明
varスコープから除去する変数名を指定する。
scope変数を除去するスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)

<c:remove>タグではscopeの指定を省略した場合、全スコープの同名のオブジェクトが除去されます。このため、予期せず他のスコープのオブジェクトを除去しないよう、必ずscopeを指定するようにした方が良いでしょう。

Java
<c:remove var="name" scope="page"/>
<c:remove var="userinfo" scope="session"/>

<c:out>

<c:out>タグはJSPコンテンツへの出力を行います。式による指定された出力内容がnullであった場合に

属性名必須説明
valueJSPコンテンツに出力する値を指定する。
defaultvalueの値がnullの場合に、替わりに出力する値を指定する。
escapeXmlXMLやHTMLに利用される所定の文字を出力する際に、エスケープするかどうかを true(デフォルト)/false のいずれかで指定する。
「< (→ &gt; )」「> (→ &lt; )」「 " (→ &quot; )」「 ' (→ &apos; )」「& (→ &amp; )」の5文字が対象。

value属性にはリテラルまたは式を指定できますが、リテラルは通常のHTMLとして記述すれば良いので、一般的には式の出力のために利用されます。

Java
<c:out value="${userinfo.userName}さん" default="名無しさん"/>


escapeXml属性は、XMLやHTMLのタグに利用される文字列をエスケープするかを指定します。falseを指定した場合、出力される変数の値(文字列)がHTML文字列であったときに、そのままHTMLとして出力されます。

Java
<%
  String html = "<p style=\"color: red;\">HTMLとしての出力</p>";
  pageContext.setAttribute("htmlContents", html);
%>
<c:out value="${htmlContents}" escapeXml="true"/>
<hr/>
<c:out value="${htmlContents}" escapeXml="false"/>

表示結果:

出力されるHTMLソース:

<c:catch>

<c:catch>タグは、JSP上で発生した例外をcatchすることができます。また、catchした例外オブジェクトは、以降のタグで利用することができます。

属性名必須説明
varcatchした例外を格納する変数名を指定する。
(pageスコープでのみ利用可能)

以下のサンプルコードでは、スクリプトレットで発生した例外をcatchして、例外オブジェクト内のエラーメッセージを出力しています。

HTML
<c:catch var="ex">
  <%
    String s = null;
    int len = s.length();
  %>
</c:catch>

<%-- catchした例外の利用例 --%>
<c:if test="${ex != null}">
  <c:out value="${ex.message}" />
</c:if>


実行結果:

条件判定・分岐の制御

<c:if>指定した条件に合致した場合のみ、ボディ部の出力を行う。
<c:choose>Javaのswitch-case文と同じように、合致した条件に応じた処理を行う。
<c:when><c:choose>タグ内判定条件を指定し、合致した場合にボディ部の出力を行う。
<c:otherwise><c:choose>タグ内で全ての条件が合致しなかった場合にボディ部の出力を行う。

<c:if>

<c:if>タグでは、条件判定を行って合致した場合のみ出力する内容を指定することができます。また、判定結果を変数に保持しておき、他のタグで同様の判定を行う際に、その結果を使いまわすことも可能です。

属性名必須説明
test判定条件を指定する。
var※3判定した結果(boolean値)を格納する変数名を指定する。
scopevar で指定した変数を保持するスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
※3 <c:if>タグがボディ部を持たない場合は指定が必要


条件判定はJavaの式やEL式を用いて指定することができ、EL式で複数条件を指定したり、<c:if>タグのネストを利用した分岐も可能です。

Java
<%-- EL式の or や and で複数条件を指定可能 --%>
<c:if test="${userinfo.userName == null or userinfo.userName.isEmpty()}">
  こんにちは、<c:out value="名無しさん" />
</c:if>

<%-- c:ifタグのネストも可能 --%>
<c:if test="${userinfo.userName != null}">
  <c:if test="${userinfo.userName.isBlank()}">
    こんにちは、<c:out value="名無しさん" />
  </c:if>
  <c:if test="${not userinfo.userName.isBlank()}">
    こんにちは、<c:out value="${userinfo.userName}さん" />
  </c:if>
</c:if>

<%-- 判定結果をvarで指定した変数に入れておき、使いまわすことも可能 --%>
<c:if var="blank" test="${userinfo.userName == null or userinfo.userName.isBlank()}" />
<c:if test="${not blank}">
  こんにちは、<c:out value="${userinfo.userName}さん" />
</c:if>

<c:choose> および <c:when><c:otherwise>

<c:choose> および <c:when><c:otherwise>のタグは、複数の条件を設定して合致した条件の箇所のみ出力することができます。これらのタグは、必ず組み合わせて使用する必要があります。(いずれのタグも単独での使用はできません)

Javaのswitch-case文に置き換えると、<c:choose>タグがswitch句、<c:when>タグがcase句に近いと考えるとわかりやすいかもしれません。ただし、Javaのswitch-case文とは違い、複数の条件に合致した場合は最初に合致した条件の箇所のみ出力し、他の条件の箇所は出力されません。

<c:otherwise>タグは、<c:when>タグに指定した条件が全て合致しなかった場合の出力内容を指定します。<c:otherwise>タグを設定しなかった場合、条件が全て合致しない時は何も出力されません。

属性名必須説明
test判定条件を指定する。
※chooseタグ、otherwiseタグは属性を持たない

以下のサンプルコードでは、変数amountの値によって文字の色を変更して文字列を出力しています。

Java
<c:choose>
  <c:when test="${ amount ge 100 }">
    <p style="color:red;">${amount}</p>
  </c:when>
  <c:when test="${ amount ge 50 }">
    <p style="color:orange;">${amount}</p>
  </c:when>
  <c:otherwise>
    <p style="color:black;">${amount}</p>
  </c:otherwise>
</c:choose>


また、空文字の判定などを if ~ elseif ~ else のように記述することも可能です。

HTML
<c:choose>
  <c:when test="${ userinfo == null }">
    こんにちは、名無しさん。
  </c:when>
  <c:when test="${ userinfo.userName.isBlank() }">
    こんにちは、名無しさん。
  </c:when>
  <c:otherwise>
    こんにちは、<c:out value="${ userinfo.userName }" />さん。
  </c:otherwise>
</c:choose>

繰り返し処理の制御

<c:forEach>配列、コレクションに対して繰り返し処理を行う。
<c:forTokens>カンマ区切りなど、区切り文字で連結された文字列を対象に、区切り文字で分割した結果に対して繰り返し処理を行う。

<c:forEach>

<c:forEach>タグは、配列やList、Mapなどのコレクションオブジェクトに対し、繰り返し処理を行うことができます。

属性名必須説明
itemsループ処理を行う対象の配列、コレクションを指定する。
varループごとに、ループ対象から取得したオブジェクトを格納する変数名を指定する。
varStatusループの状態や情報にアクセスするためのオブジェクトを格納する変数名を指定する。
beginループを開始するインデックスを0以上の数値で指定する。
デフォルト値は 0 (先頭から処理)。
※要素数以上の値
endループを終了するインデックスを0以上の数値で指定する。
デフォルトは最後まで。
stepループごとにインデックスをいくつ進めるかを1以上の数値で指定する。
デフォルトは 1 。

以下のサンプルコードでは、countries配列の各項目「America」「Belgium」「China」「Denmark」を順に出力しています。

Java
<%
  String[] array = {"America", "Belgium", "China", "Denmark"};
  pageContext.setAttribute("countries", array);
%>

<c:forEach var="country" items="${countries}">
  <p><c:out value="${country}" /></p>
</c:forEach>


<c:forEach>タグではvarSatusに指定した変数を利用することで、処理中に繰り返し処理の状況などを取得することができます。varSatusに指定した変数から取得できるプロパティは以下の通りです。

プロパティ 内容
index繰り返し処理の現在のインデックス位置。(0 ~)
current現在の繰り返し処理で利用しているオブジェクト(コレクション内の要素)
count現在の繰り返し処理が何回目の処理か(1 ~)の値。
begin、end、stepなどの指定も反映された「実際に処理が行われるのが何回目か」が返される。
first現在の処理が、繰り返し処理の初回の処理かどうかを示すboolean値。
count同様にbegin、end、stepなどの指定も含め判断される。
last現在の処理が、繰り返し処理の最後の処理かどうかを示すboolean値
count同様にbegin、end、stepなどの指定も含め判断される。
beginforEachタグのbegin属性に指定した値。指定していなかった場合はnull。
endforEachタグのend属性に指定した値。指定していなかった場合はnull。
stepforEachタグのstep属性に指定した値。指定していなかった場合はnull。

以下のサンプルコードでは、varStatusの値がどのように出力されるかが確認できます。

Java
<%
  String[] array = {"America", "Belgium", "China", "Denmark", "England", "France", "Germany", "Hungary"};
  pageContext.setAttribute("countries", array);
%>

<c:forEach var="country" items="${countries}" varStatus="st" begin="1" end="7" step="3">
  <p>${country}</p>
  <p>現在位置:${st.index}, 処理回数: ${st.count}, 現在のオブジェクト:${st.current}
  <p>first:${st.first}, last:${st.last}, begin:${st.begin}, end:${st.end}, step:${st.step}</p>
  <hr/> 
</c:forEach>


実行結果:

<c:forTokens>

<c:forTokens>タグは、文字列を指定された区切り文字で分割し、分割された個々の文字列に対して繰り返し処理を行うことができます。

属性名必須説明
items分割する対象の文字列を指定する。
delimsitemsに指定した文字列を分割する区切り文字を指定する。
varループごとに、分割された文字列を格納する変数名を指定する。
beginループを開始するインデックスを0以上の数値で指定する。
デフォルト値は 0 (先頭から処理)。
endループを終了するインデックスを0以上の数値で指定する。
デフォルトは最後まで。
stepループごとにインデックスをいくつ進めるかを1以上の数値で定する。
デフォルトは 1 。

以下のサンプルコードでは、countriesの文字列「America,Belgium,China,Denmark」をカンマで分割して、順に出力しています。

Java
<c:set var="countries" value="America,Belgium,China,Denmark" />

<c:forTokens var="country" items="${countries}" delims=",">
  <p><c:out value="${country}" /></p>
</c:forTokens>

Webアプリケーションの機能

<c:param><c:import>、<c:redirect>、<c:url>の使用時に、リクエストパラメーターを設定する。
<c:import>他のファイルをJSPに内包(インポート)させる。
<c:redirect>クライアントへ、URLの転送(リダイレクト)要求を送信する。
<c:url>URLエンコードを行う。

<c:param>

<c:param>タグは<c:import><c:redirect><c:url>タグの子要素として利用され、親要素の実行時のリクエストパラメーターを設定することができます。

属性名必須説明
nameパラメーター名を指定する。
valueパラメーターの値を指定する。

リクエストパラメーターとして送信する値は、value属性またはボディ部に設定します。どちらも設定されなかった場合は、空の値のパラメーターとして送信されます。また、両方に設定された場合は属性に設定された値が送信されます。

Java
<c:redirect url="redirect.jsp">
  <c:param name="name" value="Taro"/>
</c:redirect>

<c:redirect url="redirect.jsp">
  <c:param name="name">Taro</c:param>
</c:redirect>


同名のパラメーターを複数回設定することで、親タグの実行時に配列パラメーターとして引き渡すことができます。この時、<c:forEach>タグを利用して、繰り返し処理として複数回パラメーターを設定することもできます。

Java
<%-- 同名のパラメーターを複数回設定する --%>
<c:redirect url="redirect.jsp">
  <c:param name="name" value="Taro"/>
  <c:param name="name" value="Jiro"/>
  <c:param name="name" value="Saburo"/>
</c:redirect>


<%-- c:forEach を利用したパラメーターの設定例 --%>
<%
  String[] arr = {"Taro","Jiro","Saburo"};
  pageContext.setAttribute("prms", arr);
%>

<c:redirect url="redirect.jsp">
  <c:forEach items="${prms}" var="prm">
    <c:param name="name" value="${prm}"/>
  </c:forEach>
</c:redirect>

<c:import>

<c:import>タグでは、JSP内に他のJSPやHTMLなどのファイルを内包(インポート)させることができます。これは標準アクションの<jsp:include>と同様に動的なインポートです。

属性名必須説明
urlJSPに内包(インポート)させるファイルのURLを指定する。
varインポートしたリソースを格納する変数名を指定する。
varReaderバイナリデータを読み込む場合に、インポートしたリソースを格納する変数名を指定する。
charEncodingインポートするファイルの文字エンコーディングを指定する。
contextインポートするファイルのコンテキストパスを指定する。
scopevar で指定した変数を保持するスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)

以下のサンプルコードでは、別のJSPファイルである include.jsp を取りこみ、ページ内に表示しています。

Java
<c:import url="include.jsp" context="/WebPractice" />

<c:redirect>

<c:redirect>タグは、ページの転送(リダイレクト)を設定することができます。リダイレクトより前に記述された処理は実行されますので、処理結果によって転送先を振り分けることなども可能です。

属性名必須説明
urlリダイレクト先のURLを指定する。
contextリダイレクト先のコンテキストパスを指定する。

転送先のアドレスはurl属性に指定します。コンテキストから指定する場合は、url、contextとも「/」で始まる文字列である必要があります。

Java
<c:redirect url="redirect.jsp" />
<c:redirect url="../jsp/redirect.jsp" />

<%-- コンテキストから指定 --%>
<c:redirect url="/jsp/redirect.jsp" context="/WebPractice" />

<c:url>

<c:url>タグでは、クエリストリングで引き渡すパラメーター値に、日本語やURLで利用する記号(コロンやスラッシュなど)が含まれている場合に、URLエンコードしたURLの文字列を生成します。

属性名必須説明
value<c:url>タグによってエンコードされるURLのベースとなるURLを指定する。
varURLエンコードされたURLを格納する変数名を指定する。
contextURLのコンテキストパスを指定する。
scopevar で指定した変数を保持するスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)

下記のサンプルコードでは、日本語の「太郎」をパラメーターに指定したURLを生成して、リンクのhref属性(リンク先URL)の値に設定しています。

Java
<c:url var="enc" value="redirect.jsp">
  <c:param name="name" value="太郎" />
</c:url>
<a href="${enc}">次へ</a>


上記のサンプルからは、以下のHTMLが出力されます。「太郎」が「%e5%a4%aa%e9%83%8e」にURLエンコードされているのがわかります。

HTML
<a href="redirect.jsp?name=%e5%a4%aa%e9%83%8e">次へ</a>





いかがでしたでしょうか。今回はJSTLの導入と、coreタグライブラリの利用について解説しましたが、これらのタグを使いこなすことで、JSPの可読性、保守性を高めることにつながります。次回以降の記事では、coreタグライブラリに次いで利用されることの多い、functionsタグやfmtタグなどの利用について解説していきます。

株式会社GSI 採用サイト

新しいこと、始めよう

あなたとともに歩を進めるWEBメディア

広告

広告