
サーブレット&JSPの基本|JSPを簡潔にするEL式
JSPからJavaコードを減らして、画面表示をもっと読みやすくする。EL式でJavaBeansの値をすっきり出力しよう
JSPは、Webアプリケーションのビューとして画面表示を担当するファイルです。
サーブレットやモデルで処理した結果を受け取り、HTMLとしてブラウザに表示する役割を持っています。
これまでの学習では、リクエストスコープ、セッションスコープ、アプリケーションスコープなどにJavaBeansインスタンスを保存し、JSP側でその値を取り出して表示してきました。
たとえば、スコープに保存されたJavaBeansをJSPで表示するとき、次のような処理を書いていました。
まず、pageディレクティブでJavaBeansのクラスをimportします。
次に、getAttributeでスコープからインスタンスを取得します。
さらに、取得したObject型のインスタンスを本来の型にキャストします。
最後に、getterメソッドを呼び出してプロパティの値を表示します。
この書き方は、Javaの処理としては自然です。しかし、画面表示を担当するJSPの中にJavaコードが増えてしまうため、JSPが読みにくくなりやすいという問題があります。
そこで役立つのが、EL式です。
EL式は、Expression Languageの略で、JSPの中でスコープに保存された値やJavaBeansのプロパティを簡潔に取り出すための記法です。
たとえば、sessionスコープにmemberという属性名で保存されたJavaBeansのnameプロパティを表示したい場合、EL式では次のように書けます。
${member.name}
とても短く、HTMLの中にも自然に書きやすい形です。
この記事では、EL式の基本的な書き方、スコープとの関係、EL式の暗黙オブジェクト、JavaBeansのプロパティ取得、演算子、コレクションの扱い、そしてスクリプト要素との関係について学習していきます。
EL式とは
EL式は、JSPの中で値を簡潔に出力するための書き方です。
スコープに保存されたインスタンスや、そのインスタンスが持つプロパティを、短い記述で取り出せます。
基本形は、ドル記号と中カッコを使って書きます。
${式}
中カッコの中に書く内容が、EL式として評価されます。
たとえば、memberという属性名でスコープに保存されているインスタンスを取得したい場合は、次のように書きます。
${member}
memberインスタンスのnameプロパティを表示したい場合は、次のように書きます。
${member.name}
このように、属性名とプロパティ名をドットでつなぐことで、JavaBeansのgetterメソッドを自動的に呼び出せます。
これまでのJSPの書き方
EL式を使わない場合、JSPでJavaBeansの値を表示するには、いくつかの手順が必要でした。
たとえば、セッションスコープにmemberという属性名でMemberインスタンスが保存されているとします。
そのnameプロパティを表示する場合、従来の書き方では次のような流れになります。
<%@ page import="model.Member" %>
<%
Member member =
(Member) session.getAttribute("member");
%>
<%= member.getName() %>この書き方では、JSPの中にJavaの処理が入っています。
従来の書き方で必要な処理
| 処理 | 内容 |
|---|---|
| import | JSPでMemberクラスを使えるようにする |
| getAttribute | セッションスコープからmemberを取得する |
| キャスト | Object型をMember型に変換する |
| getter呼び出し | getNameでnameプロパティを取得する |
| スクリプト式 | 取得した値をHTML内に出力する |
このように、1つの値を表示するだけでも、JSP内にJavaコードが増えてしまいます。
JSPを画面表示中心のファイルとして見やすく保つには、もう少し簡潔な書き方が望ましいです。
EL式を使った書き方
EL式を使うと、先ほどの処理は次のように書けます。
${member.name}これだけで、スコープに保存されたmemberインスタンスを探し、そのnameプロパティを取得して出力できます。
従来の書き方とEL式の違い
| 内容 | 従来の書き方 | EL式 |
|---|---|---|
| クラスのimport | 必要 | 不要 |
| getAttribute | 必要 | 不要 |
| キャスト | 必要 | 不要 |
| getterメソッドの呼び出し | 必要 | 自動で行われる |
| 表示用の記述 | <%= member.getName() %> | ${member.name} |
EL式を使うと、JSP内のJavaコードを大きく減らせます。
その結果、JSPがHTMLに近い見た目になり、画面の構造を読み取りやすくなります。
図1:EL式でJavaBeansのプロパティを簡潔に表示する

この図から分かること
EL式を使うと、JSP内でJavaBeansのプロパティを簡潔に表示できます。
従来は、クラスのimport、getAttributeによる取得、キャスト、getterメソッドの呼び出し、スクリプト式による出力が必要でした。
EL式では、${member.name}のように書くだけで、スコープに保存されたmemberインスタンスを探し、nameプロパティのgetterメソッドを自動的に呼び出して値を出力できます。
EL式の基本文法
EL式は、属性名やプロパティ名を使って値を取得します。
基本的な書き方は、次の2つです。
スコープに保存されたインスタンスを利用するEL式
| 書き方 | 内容 |
|---|---|
| ${属性名} | スコープに保存されているインスタンスを取得する |
| ${属性名.プロパティ} | スコープに保存されているインスタンスのプロパティ値を取得する |
たとえば、memberという属性名で保存されたMemberインスタンスがあるとします。
そのインスタンス自体を参照する場合は、${member}と書きます。
そのインスタンスのnameプロパティを表示する場合は、${member.name}と書きます。
プロパティ名を指定すると、対応するgetterメソッドが自動的に実行されます。
プロパティ名とgetterメソッドの関係
EL式では、プロパティ名を指定すると、自動的にgetterメソッドが呼び出されます。
たとえば、次のEL式を考えます。
${member.name}この場合、memberインスタンスのgetNameメソッドが呼び出されます。
EL式とgetterメソッドの対応
| EL式 | 自動的に呼び出されるgetter |
|---|---|
| ${member.name} | getName |
| ${member.age} | getAge |
| ${studyPace.goalHours} | getGoalHours |
| ${studyPace.actualHours} | getActualHours |
ここで指定するのは、フィールド名そのものというより、JavaBeansのプロパティ名です。
たとえば、getNameというgetterがある場合、EL式ではnameと書きます。
getGoalHoursというgetterがある場合、EL式ではgoalHoursと書きます。
もし、指定したプロパティに対応するgetterメソッドが存在しない場合は、PropertyNotFoundExceptionが発生することがあります。
EL式とスコープの関係
EL式では、スコープに保存されたインスタンスを自動的に探してくれます。
たとえば、${member.name}と書いた場合、EL式はmemberという属性名のインスタンスをスコープから探します。
このとき、検索するスコープには順番があります。
EL式が検索するスコープの順番
| 順番 | スコープ |
|---|---|
| 1 | ページスコープ |
| 2 | リクエストスコープ |
| 3 | セッションスコープ |
| 4 | アプリケーションスコープ |
EL式は、まずページスコープを探します。
見つからなければリクエストスコープを探します。
そこにもなければセッションスコープを探します。
最後にアプリケーションスコープを探します。
この順番で属性名を探し、最初に見つかったインスタンスを利用します。
ページスコープとは
ページスコープは、JSPファイルだけが持つスコープです。
ページスコープに保存したインスタンスは、そのJSPファイルの中でだけ利用できます。
4種類のスコープ
| スコープ | 主な用途 |
|---|---|
| ページスコープ | そのJSP内だけで使う情報 |
| リクエストスコープ | フォワード先まで一時的に渡したい情報 |
| セッションスコープ | ログイン中のユーザー情報など、利用者ごとに保持したい情報 |
| アプリケーションスコープ | 全ユーザーで共有したい情報 |
これまでよく使ってきたのは、リクエストスコープ、セッションスコープ、アプリケーションスコープです。
EL式では、これらに加えてページスコープも検索対象になります。
属性名が見つからない場合
EL式で指定した属性名が、どのスコープにも存在しない場合があります。
たとえば、memberという属性名でどのスコープにもインスタンスが保存されていない状態で、次のように書いたとします。
${member.name}この場合、例外が発生せず、何も出力されないことがあります。
属性名が見つからない場合の注意
| 状況 | 結果 |
|---|---|
| 指定した属性名がスコープにない | 何も表示されない |
| 例外が出るか | 基本的には例外が出ず、気づきにくい |
| 注意点 | 属性名の書き間違いや保存漏れに気づきにくい |
何も表示されないだけだと、画面の作り方が間違っているのか、サーブレット側でsetAttributeを忘れているのか、属性名がずれているのかが分かりにくくなります。
EL式を使うときは、サーブレット側で保存した属性名と、JSP側で指定する属性名が一致しているかを丁寧に確認しましょう。
同じ属性名が複数のスコープにある場合
EL式は、ページスコープ、リクエストスコープ、セッションスコープ、アプリケーションスコープの順に属性を探します。
そのため、複数のスコープに同じ属性名のインスタンスが保存されている場合、先に見つかったものが使われます。
たとえば、リクエストスコープとセッションスコープの両方にmsgという属性名のインスタンスが保存されているとします。
この状態で次のように書くと、リクエストスコープのmsgが優先されます。
${msg}セッションスコープのmsgを使いたい場合は、検索するスコープを明示します。
${sessionScope.msg}同じ属性名がある場合の動き
| 状態 | ${msg}で取得されるもの |
|---|---|
| リクエストスコープにmsgがある | リクエストスコープのmsg |
| リクエストスコープになく、セッションスコープにmsgがある | セッションスコープのmsg |
| セッションスコープになく、アプリケーションスコープにmsgがある | アプリケーションスコープのmsg |
同じ属性名を複数のスコープで使うと、どの値が表示されているのか分かりにくくなることがあります。
必要に応じて、EL式の暗黙オブジェクトを使い、検索対象のスコープを明示しましょう。
図2:EL式がスコープを探す順番

この図から分かること
EL式でスコープを指定しない場合、ページスコープ、リクエストスコープ、セッションスコープ、アプリケーションスコープの順に属性名を探します。
同じ属性名が複数のスコープにある場合は、先に見つかったインスタンスが利用されます。
特定のスコープから取得したい場合は、sessionScopeやrequestScopeのようなEL式の暗黙オブジェクトを使って、検索対象を明示できます。
EL式の暗黙オブジェクト
EL式には、スコープやリクエスト情報を扱うための暗黙オブジェクトが用意されています。
これは、JSPの暗黙オブジェクトとは別物です。
JSPの暗黙オブジェクトには、request、response、session、applicationなどがあります。
一方、EL式の暗黙オブジェクトには、requestScope、sessionScope、paramなどがあります。
主なEL式の暗黙オブジェクト
| 暗黙オブジェクト名 | 説明 |
|---|---|
| pageScope | ページスコープを表す |
| requestScope | リクエストスコープを表す |
| sessionScope | セッションスコープを表す |
| applicationScope | アプリケーションスコープを表す |
| param | リクエストパラメータの名前と値を対応させたMapオブジェクト |
| header | リクエストヘッダーの名前と値を対応させたMapオブジェクト |
| cookie | クッキーの名前と値を対応させたMapオブジェクト |
たとえば、セッションスコープに保存されたloginUserを明示的に取得したい場合は、次のように書けます。
${sessionScope.loginUser.name}リクエストスコープに保存されたerrorMsgを明示的に取得したい場合は、次のように書けます。
${requestScope.errorMsg}スコープを明示すると、どのスコープの値を表示しているのか分かりやすくなります。
JSPの暗黙オブジェクトとの違い
EL式の暗黙オブジェクトと、JSPの暗黙オブジェクトは名前が似ているものがあります。
しかし、同じものではありません。
JSPの暗黙オブジェクトとEL式の暗黙オブジェクト
| 用途 | JSPの暗黙オブジェクト | EL式の暗黙オブジェクト |
|---|---|---|
| セッションを扱う | session | sessionScope |
| リクエストを扱う | request | requestScope |
| アプリケーションを扱う | application | applicationScope |
JSPのスクリプトレット内で使う場合は、session.getAttributeのようにJSPの暗黙オブジェクトを使います。
EL式の中で使う場合は、${sessionScope.loginUser}のようにEL式用の暗黙オブジェクトを使います。
表記が異なるため、混同しないようにしましょう。
EL式でJSPを改良する
ここからは、EL式を使ってJSPを簡潔にする例を見ていきます。
今回は、学習ペース診断の結果画面を表示するJSPを例にします。
サーブレット側で、診断結果を表すStudyPaceインスタンスを作成し、studyPaceという属性名でリクエストスコープに保存しているとします。
StudyPaceインスタンスには、次のようなプロパティがあるものとします。
StudyPaceインスタンスのプロパティ
| プロパティ | 内容 | 対応するgetter |
|---|---|---|
| goalHours | 目標学習時間 | getGoalHours |
| actualHours | 実際の学習時間 | getActualHours |
| achievementRate | 達成率 | getAchievementRate |
| judgment | 判定 | getJudgment |
EL式を使うと、これらのプロパティをJSPで簡潔に表示できます。
EL式を使用したJSPファイルの例
ファイル名: studyCheckResult.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学習ペース診断</title>
</head>
<body>
<h1>学習ペース診断の結果</h1>
<p>
目標学習時間:${studyPace.goalHours}時間<br>
実際の学習時間:${studyPace.actualHours}時間<br>
達成率:${studyPace.achievementRate}%<br>
判定:${studyPace.judgment}
</p>
<a href="StudyCheck">戻る</a>
</body>
</html>studyCheckResult.jspは、src/main/webapp/WEB-INF/jspディレクトリに配置する想定です。
このJSPでは、JavaBeansのクラスをimportしていません。
また、request.getAttributeでstudyPaceを取得していません。
それでも、${studyPace.goalHours}のように書くことで、スコープに保存されたStudyPaceインスタンスのプロパティを表示できます。
ブラウザの表示例

EL式を使うと不要になる記述
EL式を使うと、JSP内のJavaコードをかなり減らせます。
先ほどのstudyCheckResult.jspでは、次のような記述が不要になっています。
EL式によって不要になるもの
| 従来必要だったもの | EL式で不要になる理由 |
|---|---|
| StudyPaceクラスのimport | EL式ではクラスを直接指定しないため |
| request.getAttribute | EL式がスコープから属性名を探すため |
| StudyPace型へのキャスト | EL式が取得したインスタンスのプロパティを扱うため |
| getGoalHoursなどのgetter呼び出し | プロパティ名を書くとgetterが自動実行されるため |
| スクリプト式 | EL式をHTML内に書くだけで出力されるため |
JSPは画面表示を担当するファイルです。
EL式を使うことで、Javaの処理を減らし、HTMLに近い形で画面を作成しやすくなります。
EL式のプロパティ取得で注意すること
EL式では、プロパティ名を書くとgetterメソッドが自動的に呼び出されます。
たとえば、次のEL式では、StudyPaceインスタンスのgetGoalHoursメソッドが呼び出されます。
${studyPace.goalHours}ここで大切なのは、StudyPaceクラスにgetGoalHoursメソッドが存在することです。
もし、プロパティ名に対応するgetterメソッドが存在しない場合、PropertyNotFoundExceptionが発生することがあります。
注意したい例
| EL式 | 必要なgetter |
|---|---|
| ${studyPace.goalHours} | getGoalHours |
| ${studyPace.actualHours} | getActualHours |
| ${studyPace.achievementRate} | getAchievementRate |
| ${studyPace.judgment} | getJudgment |
EL式でうまく表示されない場合は、サーブレット側でスコープに保存している属性名、JavaBeansのプロパティ名、getterメソッドの名前を確認しましょう。
図3:EL式で診断結果画面をすっきり表示する

この図から分かること
サーブレット側でStudyPaceインスタンスをstudyPaceという属性名でリクエストスコープに保存しておくと、JSP側ではEL式で簡潔に表示できます。
studyCheckResult.jspでは、${studyPace.goalHours}のように書くだけで、StudyPaceインスタンスのgetterメソッドが自動的に呼び出されます。
これにより、JSP内にimport、getAttribute、キャスト、getter呼び出し、スクリプト式を書かずに済みます。
EL式の特徴
EL式には、JSPを簡潔にするための便利な特徴があります。
EL式の主な特徴
| 特徴 | 内容 |
|---|---|
| スコープを自動検索する | 属性名を指定すると、複数のスコープから探してくれる |
| importが不要 | JavaBeansのクラスをJSPでimportしなくてもよい |
| getAttributeが不要 | EL式がスコープから属性を探す |
| getterを自動実行する | プロパティ名を書くと対応するgetterが呼び出される |
| HTML内に直接書ける | テンプレートに書くだけで結果が出力される |
この特徴により、JSPはより画面表示に集中したファイルになります。
Javaの処理をなるべくサーブレットやモデルに寄せ、JSPではEL式で値を表示する、という役割分担がしやすくなります。
EL式の演算子
EL式では、値を表示するだけでなく、演算子も使えます。
多くの演算子はJavaに近い感覚で利用できます。
たとえば、年齢に1を足したり、数値を比較したりできます。
通常の演算子の例
| EL式 | 結果の例 |
|---|---|
| ${member.age + 1} | ageが23なら24 |
| ${member.age >= 18} | ageが23ならtrue |
| ${studyPace.achievementRate >= 80} | 達成率が80以上ならtrue |
演算子を使うことで、JSP内で簡単な計算や比較ができます。
ただし、複雑な業務処理をJSPに書きすぎると、画面と処理の役割が混ざってしまいます。
本格的な計算や判定は、できるだけサーブレットやモデルで行い、JSPでは表示に必要な簡単な式にとどめると整理しやすくなります。
empty演算子
EL式には、Javaにはない便利な演算子もあります。
その代表がempty演算子です。
empty演算子は、対象が空かどうかを判定します。
基本形は次のように書きます。
${empty 対象}対象が空の場合、trueを返します。
empty演算子がtrueになる主な条件
| 対象の状態 | 結果 |
|---|---|
| スコープに保存されていない | true |
| null | true |
| 空文字 | true |
| 要素数が0の配列 | true |
| 要素を1つも持たないListやMapなどのコレクション | true |
たとえば、errorMsgがリクエストスコープに存在しない場合、次のEL式はtrueになります。
${empty errorMsg}逆に、errorMsgが存在していて空でない場合はfalseになります。
not empty演算子
empty演算子の結果を反転したい場合は、not empty演算子を使います。
${not empty errorMsg}これは、errorMsgが存在し、空でない場合にtrueになります。
emptyとnot emptyの例
| EL式 | 意味 |
|---|---|
| ${empty member} | memberが存在しない、または空ならtrue |
| ${not empty member} | memberが存在し、空でなければtrue |
| ${empty errorMsg} | errorMsgがない、または空ならtrue |
| ${not empty errorMsg} | errorMsgがあるならtrue |
empty演算子は、次に学習する条件分岐と組み合わせると便利です。
たとえば、エラーメッセージがある場合だけ表示する、といった処理でよく使います。
EL式とコレクション
Webアプリケーションでは、リストやマップをスコープに保存して、JSPで表示することがあります。
たとえば、投稿一覧、商品一覧、検索結果、利用者一覧などです。
EL式では、リストやマップの中にある要素を取り出せます。
コレクションを利用するEL式
| 対象 | 書き方 |
|---|---|
| リスト内のインスタンスを取得する | ${属性名[インデックス]} |
| リスト内のインスタンスのプロパティを取得する | ${属性名[インデックス].プロパティ} |
| マップ内のインスタンスを取得する | ${属性名["キー"]} |
| マップ内のインスタンスのプロパティを取得する | ${属性名["キー"].プロパティ} |
たとえば、memberListという属性名でListがスコープに保存されているとします。
0番目のMemberインスタンスのnameプロパティを表示したい場合は、次のように書けます。
${not empty errorMsg}0番目のMemberインスタンスのageプロパティを表示したい場合は、次のように書けます。
${memberList[0].age}リストをEL式で扱うイメージ
リストは、0番目、1番目、2番目というように、インデックス番号で要素を管理します。
EL式では、角カッコを使ってインデックスを指定できます。
memberListの例
| インデックス | name | age |
|---|---|---|
| 0 | 山田 | 23 |
| 1 | 青山 | 22 |
| 2 | 佐藤 | 25 |
このmemberListがスコープに保存されている場合、次のEL式で値を取り出せます。
| EL式 | 表示される値 |
|---|---|
| ${memberList[0].name} | 山田 |
| ${memberList[0].age} | 23 |
| ${memberList[1].name} | 青山 |
| ${memberList[2].name} | 佐藤 |
リスト内のインスタンスも、JavaBeansであればドットでプロパティを指定できます。
マップをEL式で扱うイメージ
Mapをスコープに保存している場合は、キーを指定して値を取得できます。
たとえば、scoreMapという属性名でMap<String, Integer>が保存されているとします。
キーmathに対応する値を表示する場合は、次のように書けます。
${scoreMap["math"]}Mapの例
| キー | 値 |
|---|---|
| java | 85 |
| jsp | 90 |
| servlet | 88 |
このscoreMapがスコープに保存されている場合、次のように取得できます。
| EL式 | 表示される値 |
|---|---|
| ${scoreMap["java"]} | 85 |
| ${scoreMap["jsp"]} | 90 |
| ${scoreMap["servlet"]} | 88 |
Mapは、キーを使って値を取得するコレクションです。
EL式でも、キーを指定して値を取り出せます。
EL式はスクリプト要素の中では使えない
EL式は便利ですが、どこにでも書けるわけではありません。
注意したいのは、スクリプトレットやスクリプト式の中ではEL式を使えないという点です。
たとえば、次のような書き方はできません。
<% for (int i = 0; i < ${memberList.size()}; i++) { %>
<p>${memberList[i].name}</p>
<% } %>また、次のように拡張for文の対象にEL式を書くこともできません。
<% for (Member member : ${memberList}) { %>
<p>${member.name}</p>
<% } %>このような書き方はエラーになります。
EL式は、JSPのテンプレート部分に書いて値を出力するためのものです。
Javaのスクリプトレット内に埋め込んで使うものではありません。
繰り返しや条件分岐でEL式を使いたい場合
リストに入っているインスタンスを先頭から順に表示したい場合、for文を使いたくなります。
しかし、スクリプトレットのfor文の中でEL式を使うことはできません。
繰り返しや条件分岐でEL式を活用したい場合は、JSTLを使います。
JSTLを使うと、JSP内でJavaのfor文やif文を書かずに、タグ形式で繰り返しや条件分岐を表現できます。
EL式とスクリプト要素の関係
| 書き方 | 使えるか |
|---|---|
| HTML内に${member.name}を書く | 使える |
| pタグの中に${member.name}を書く | 使える |
| スクリプトレットのJavaコード内にEL式を書く | 使えない |
| for文の条件にEL式を書く | 使えない |
| JSTLのタグとEL式を組み合わせる | 使える |
EL式は、JSPからJavaコードを減らすための技術です。
そのため、スクリプトレットと無理に組み合わせるより、JSTLなどのタグと組み合わせて使うほうが自然です。
EL式を使うときに意識したいこと
EL式を使うと、JSPをかなり簡潔に書けます。
ただし、正しく使うには、スコープに保存した属性名、JavaBeansのプロパティ名、getterメソッドの対応を理解しておく必要があります。
確認したいポイント
| ポイント | 内容 |
|---|---|
| 属性名が一致しているか | サーブレットのsetAttributeとJSPのEL式で同じ名前を使う |
| getterが存在するか | プロパティ名に対応するgetterメソッドを用意する |
| 同名属性が複数スコープにないか | 必要ならrequestScopeやsessionScopeで明示する |
| 空の場合の表示を考えるか | emptyやnot emptyを使う場面を検討する |
| スクリプトレット内で使っていないか | EL式はスクリプト要素の中では使えない |
JSPは画面表示を担当するファイルです。
EL式を使うことで、JSP内のJavaコードを減らし、画面の構造を見やすくできます。
JavaBeansの値を表示するときは、まずEL式で表せないかを考えると、JSPをよりすっきり保てます。
