
EL式(Expression Language)徹底解説 – JSP開発の新たな表現力
2025-08-04EL式とは何か
Expression Language(EL式)は、JSPページ内でデータにアクセスし操作するための簡潔な言語です。JSP 2.0から標準導入され、スクリプトレットに代わるより洗練されたデータアクセス方法を提供します。
EL式の主な特徴:
- 簡潔な構文:
${expression}
形式で記述 - 自動型変換:文字列と基本データ型の自動変換
- 暗黙オブジェクトへのアクセス:簡単にスコープオブジェクトを参照
- メソッド呼び出し可能(EL 2.2以降)
- null安全:NullPointerExceptionを発生させない
従来のスクリプトレットや式と比較して、より安全で読みやすいコードを記述できます。
EL式の基本構文
基本的なEL式の形式
${expression}
スクリプトレット式との比較
スクリプトレット式:
<%= request.getAttribute("userName") %>
EL式:
${userName}
スクリプトレット式(型変換が必要):
<%= ((Integer)request.getAttribute("age")).intValue() + 10 %>
EL式(自動型変換):
${age + 10}
EL式の変数参照
スコープを指定したアクセス
スクリプトレットでのアクセス:
<%= pageContext.findAttribute("product") %>
<%= request.getAttribute("product") %>
<%= session.getAttribute("product") %>
<%= application.getAttribute("product") %>
EL式でのアクセス(自動的にすべてのスコープを検索):
${product}
明示的なスコープ指定:
${pageScope.product} <%-- ページスコープ --%>
${requestScope.product} <%-- リクエストスコープ --%>
${sessionScope.product} <%-- セッションスコープ --%>
${applicationScope.product} <%-- アプリケーションスコープ --%>
JavaBeanプロパティへのアクセス
スクリプトレットでのアクセス:
<%= ((User)request.getAttribute("user")).getName() %>
EL式でのアクセス:
${user.name}
ネストしたプロパティにもアクセス可能:
${user.address.prefecture}
EL式の演算子
算術演算子
スクリプトレット:
<%= (Integer)request.getAttribute("price") * 1.08 %>
EL式:
${price * 1.08}
主な算術演算子:
+
(加算)-
(減算)*
(乗算)/
またはdiv
(除算)%
またはmod
(剰余)
比較演算子
スクリプトレット:
<%= ((Integer)request.getAttribute("age")).intValue() >= 20 %>
EL式:
${age >= 20}
主な比較演算子:
==
またはeq
(等しい)!=
またはne
(等しくない)<
またはlt
(より小さい)>
またはgt
(より大きい)<=
またはle
(以下)>=
またはge
(以上)
論理演算子
スクリプトレット:
<%= ((Boolean)request.getAttribute("isMember")).booleanValue() &&
((Integer)request.getAttribute("age")).intValue() >= 20 %>
EL式:
${isMember && age >= 20}
主な論理演算子:
&&
またはand
(論理積)||
またはor
(論理和)!
またはnot
(否定)
その他の演算子
- empty演算子:空かどうかをチェック
${empty userList}
null
、空文字列、空のコレクション/配列の場合にtrue
- 三項演算子:
${age >= 20 ? '成人' : '未成年'}
- 括弧による優先順位の制御:
${(a + b) * c}
EL式の暗黙オブジェクト
JSPの暗黙オブジェクトに簡単にアクセスできます。
暗黙オブジェクト | 説明 | スクリプトレット相当 | EL式例 |
---|---|---|---|
pageContext | PageContextオブジェクト | pageContext | ${pageContext} |
pageScope | ページスコープの属性マップ | pageContext.getAttributes() | ${pageScope.attr} |
requestScope | リクエストスコープの属性マップ | request.getAttribute() | ${requestScope.attr} |
sessionScope | セッションスコープの属性マップ | session.getAttribute() | ${sessionScope.attr} |
applicationScope | アプリケーションスコープの属性マップ | application.getAttribute() | ${applicationScope.attr} |
param | リクエストパラメータのマップ | request.getParameter() | ${param.name} |
paramValues | 複数値のリクエストパラメータマップ | request.getParameterValues() | ${paramValues.name[0]} |
header | リクエストヘッダーのマップ | request.getHeader() | ${header[‘User-Agent’]} |
headerValues | 複数値のリクエストヘッダーマップ | request.getHeaders() | ${headerValues.Accept[0]} |
cookie | クッキーのマップ | request.getCookies() | ${cookie.JSESSIONID.value} |
initParam | コンテキスト初期化パラメータのマップ | application.getInitParameter() | ${initParam.dbURL} |
使用例:
<%-- リクエストパラメータの取得 --%>
スクリプトレット: <%= request.getParameter("username") %>
EL式: ${param.username}
<%-- セッション属性の取得 --%>
スクリプトレット: <%= session.getAttribute("currentUser") %>
EL式: ${sessionScope.currentUser}
<%-- コンテキスト初期化パラメータ --%>
スクリプトレット: <%= application.getInitParameter("maxUsers") %>
EL式: ${initParam.maxUsers}
EL式のメソッド呼び出し(EL 2.2以降)
EL 2.2からはメソッド呼び出しが可能になりました。
静的メソッドの呼び出し
スクリプトレット:
<%= java.util.UUID.randomUUID().toString() %>
EL式:
${T(java.util.UUID).randomUUID()}
インスタンスメソッドの呼び出し
スクリプトレット:
<%= user.getFullName(true) %>
EL式:
${user.getFullName(true)}
EL式の実践的な使用例
条件に基づくスタイルの適用
スクリプトレット:
<tr class="<%= ((Integer)request.getAttribute("rowIndex")) % 2 == 0 ? "even" : "odd" %>">
EL式:
<tr class="${rowIndex % 2 == 0 ? 'even' : 'odd'}">
複雑な条件表示
スクリプトレット:
<% if(user != null && user.getRole().equals("admin") &&
(request.getParameter("mode") == null ||
!request.getParameter("mode").equals("simple"))) { %>
<jsp:include page="adminPanel.jsp"/>
<% } %>
EL式:
<c:if test="${not empty user and user.role eq 'admin'
and (empty param.mode or param.mode ne 'simple')}"><
jsp:include page="adminPanel.jsp"/>
</c:if>
コレクションの操作
スクリプトレット:
<%
List<Product> products = (List<Product>)request.getAttribute("products");
for(int i=0; i<products.size(); i++) {
Product p = products.get(i);
if(p.getStock() > 0) {
%>
<div class="product <%= i % 2 == 0 ? "even" : "odd" %>">
<%= p.getName() %> - ¥<%= p.getPrice() %>
</div>
<% }} %>
EL式 + JSTL:
<c:forEach items="${products}" var="p" varStatus="status">
<c:if test="${p.stock > 0}">
<div class="product ${status.index % 2 == 0 ? 'even' : 'odd'}">
${p.name} - ¥${p.price}
</div>
</c:if>
</c:forEach>
EL式のベストプラクティス
- スクリプトレットよりEL式を優先
- 可能な限りスクリプトレットではなくEL式を使用
- 適切なスコープの使用
- 必要に応じて明示的にスコープを指定(
${requestScope.user}
など) - 不要なスコープ検索を避ける
- null安全を活用
- nullチェックを簡潔に記述
<%-- 従来のnullチェック --%>
<%= (user != null) ? user.getName() : "" %>
<%-- EL式のnull安全 --%>
${user.name}
- 複雑なロジックは避ける
- EL式内で複雑な処理を行わず、ServletやJavaクラスで処理
- 式の可読性を考慮
- 長すぎる式は分割して記述
- 必要に応じてコメントを追加
- EL式の無効化
- 必要に応じてEL式を無効化可能
<%@ page isELIgnored="true" %>
EL式のデバッグ方法
- 直接出力して確認
Debug: ${variable}
- 暗黙オブジェクトの内容確認
PageContext: ${pageContext}
Request parameters: ${param}
Session attributes: ${sessionScope}
- 型情報の確認
Type of variable: ${variable['class'].name}
- デフォルト値の使用
${empty variable ? '変数は空です' : variable}
EL式の制限事項
- 変数の宣言不可
- EL式では新しい変数を宣言できません(
<c:set>
タグを使用)
- 制御フローの制限
- 条件分岐やループはJSTLタグと組み合わせて使用
- 複雑なロジックの制限
- 複雑なビジネスロジックには不向き
- EL 2.2以前の制限
- メソッド呼び出しができない(EL 2.2以前)
まとめ
EL式はJSP開発において以下のような大きな利点をもたらします:
- 簡潔さ:スクリプトレットに比べてコードが大幅に短縮
- 可読性:HTMLとの混在が自然で理解しやすい
- 安全性:自動null処理や型変換による堅牢性
- 保守性:ロジックとプレゼンテーションの分離が容易
EL式をマスターすることで、JSPページの開発効率と品質を大幅に向上させることができます。JSTLと組み合わせることで、スクリプトレットをほとんど使用しない、モダンで保守性の高いJSPページを作成可能です。
次にカスタムタグを学ぶことで、さらに高度なテンプレート処理や独自のタグライブラリを作成するスキルを身につけることができます。EL式はそれらの技術の基盤としても重要な役割を果たしますので、基本的な使い方をしっかりと理解しておきましょう。