6.

JSP 完全ガイド — Servlet 連携・JSTL・EL・現代の代替まで

編集
この記事の要点
  • JSP (JavaServer Pages) は HTML 内に Java コードを埋め込んで動的ページを生成する技術。実体はサーバ起動時に Servlet へコンパイルされる
  • スクリプトレット <% %>非推奨。現代は JSTL + EL でロジックを書く
  • JSP は Java EE 標準だが Thymeleaf / Mustache / SPA + REST に置き換える流れ
  • Jakarta EE 9 以降はパッケージが javax.servlet.*jakarta.servlet.* に変更(Tomcat 10+ / Spring Boot 3+)
  • Spring Boot で JSP を使うと JAR パッケージで動かないなど制約あり。新規開発は Thymeleaf 推奨

JSP とは

JSP (JavaServer Pages) は、HTML テンプレート内に Java コードや専用タグを埋め込んで動的ウェブページを生成する Java EE 標準技術です。Tomcat / Jetty / WildFly などのサーブレットコンテナが、JSP ファイル (.jsp) を内部的に Servlet クラスへ変換・コンパイルし、リクエストごとに実行します。

JSP の動作原理 — Servlet への変換

次のような JSP は、

<%@ page contentType="text/html;charset=UTF-8" %>


こんにちは, <%= request.getParameter("name") %> さん

初回アクセス時に Tomcat 内部で次のような Servlet に変換されます:

public final class hello_jsp extends HttpJspBase {
    public void _jspService(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("text/html;charset=UTF-8");
        JspWriter out = response.getWriter();
        out.write("\n\n

こんにちは, "); out.print(request.getParameter("name")); out.write(" さん

\n\n"); } }

そのため 2 回目以降は Servlet と同じ速度で動作します。Tomcat の work ディレクトリに変換結果の .java / .class が保存されます。

JSP の構文要素

構文用途推奨度
<%@ %>ディレクティブ (ページ設定)<%@ page contentType="..." %>必須
<% %>スクリプトレット (Java コード)<% int x = 1; %>非推奨
<%= %>式 (値の出力)<%= user.getName() %>非推奨 → EL
<%! %>宣言 (メソッド・フィールド)<%! private int n; %>避ける
${ }EL (式言語)${user.name}推奨
JSTL推奨

スクリプトレットが非推奨な理由

歴史的経緯で JSP の <% %> 内に直接 Java を書くスタイルがありますが、以下の理由で新規開発では禁止するのが業界標準です。

  • ビジネスロジックがビューに混入 → MVC の View 責務違反
  • テストが困難 → JSP 単体テストは事実上不可能
  • 例外処理が貧弱 → コンパイルエラーが発見しづらい
  • デバッガが効きにくい → 行番号がずれる
  • 再利用性ゼロ → 同じロジックを複数 JSP に貼り付け

悪い例 vs. 良い例

<%-- ❌ スクリプトレット (非推奨) --%>
<%
List users = (List) request.getAttribute("users");
for (User u : users) {
    if (u.isActive()) {
%>
    
  • <%= u.getName() %>
  • <% } } %> <%-- ✅ JSTL + EL (推奨) --%>
  • ${u.name}
  • EL (Expression Language)

    EL は ${...} 形式で属性スコープから値を取り出す式言語です。JSP 2.0 以降の標準:

    <%-- スコープから取り出し (page → request → session → application 順に探索) --%>
    ${user.name}
    ${user["name"]}
    
    <%-- Map / List アクセス --%>
    ${prefs["theme"]}
    ${list[0]}
    
    <%-- 演算 --%>
    ${price * 1.1}
    ${count > 0 ? "あり" : "なし"}
    
    <%-- 関数 (functions.tld を taglib で読み込み) --%>
    ${fn:length(users)}
    ${fn:toUpperCase(name)}
    
    <%-- 暗黙オブジェクト --%>
    ${param.q}                    <%-- request.getParameter("q") --%>
    ${header["User-Agent"]}
    ${pageContext.request.contextPath}

    JSTL (JSP Standard Tag Library)

    条件分岐・繰り返し・国際化などのタグライブラリ:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    
    <%-- 条件分岐 --%>
    管理者です
    
    
        
        
        不可
    
    
    <%-- 繰り返し --%>
    
        ${st.index}: ${u.name}
    
    
    <%-- セット --%>
    
    
    <%-- フォーマット --%>
    
    
    
    <%-- URL エスケープ --%>
        <%-- XSS 対策で必須 --%>

    Maven 依存 (Jakarta EE 10):

    
        jakarta.servlet.jsp.jstl
        jakarta.servlet.jsp.jstl-api
        3.0.0
    
    
        org.glassfish.web
        jakarta.servlet.jsp.jstl
        3.0.1
    

    Servlet と JSP の連携 (MVC)

    典型的な構成: Servlet (Controller) → Model 準備 → JSP (View) へ forward

    @WebServlet("/users")
    public class UserListServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            List users = userService.findAll();
            req.setAttribute("users", users);       // ★ JSP に渡す
            req.getRequestDispatcher("/WEB-INF/views/users.jsp")
               .forward(req, resp);                  // ★ JSP に forward
        }
    }

    JSP は /WEB-INF/ 配下に置くと直接 URL で叩けなくなるためセキュリティ上有利です。

    javax → jakarta への移行 (Jakarta EE 9)

    Eclipse Foundation 移管に伴い、パッケージ名が javax.* から jakarta.* に変更されました:

    必要環境
    javax.servlet.*jakarta.servlet.*Tomcat 10+, Jetty 11+
    javax.servlet.jsp.*jakarta.servlet.jsp.*同上
    javax.persistence.*jakarta.persistence.*Hibernate 6+

    Spring Boot 3.x は jakarta 系。Tomcat 9 系 (javax) と Tomcat 10 系 (jakarta) は互換性がないので注意。

    JSP の代替テンプレートエンジン

    エンジン特徴採用例
    ThymeleafHTML として開けるナチュラルテンプレートSpring Boot 標準
    FreeMarker強力なマクロ機能古い Spring 系
    Mustacheロジックレス・他言語互換軽量 SaaS
    JTEコンパイル型・高速新興、Kotlin 親和
    SPA + RESTサーバはテンプレ持たないReact / Vue / Angular

    新規 Spring Boot プロジェクトは Thymeleaf + Bootstrap または REST API + フロント分離が主流です。

    FAQ

    Q: Spring Boot で JSP を使える?
    A: 使えますが JAR ではなく WAR パッケージングが必要で、内蔵 Tomcat の制約もあり推奨されません。Thymeleaf を使うのが定石。

    Q: JSP のパフォーマンスは?
    A: 初回コンパイルは遅いが、2 回目以降は Servlet と同じ。本番デプロイ前に precompile (jspc Maven プラグイン) しておくと初回遅延を回避できる。

    Q: XSS 対策は?
    A: 必ず または EL の fn:escapeXml() を使う。生の ${input} はエスケープされない。

    関連項目

    • Servlet — JSP のベースになる Java EE 標準
    • Thymeleaf — Spring Boot 推奨のテンプレートエンジン
    • Tomcat — もっとも普及している JSP/Servlet コンテナ
    • Jakarta EE — Java EE の後継仕様
    編集
    Post Share
    子ページ
    1. タグ一覧
    2. コンテキストパスの取得
    同階層のページ
    1. プラットホーム
    2. 環境構築
    3. 文法
    4. API
    5. Servlet(サーブレット)
    6. JSP
    7. Applet(アプレット)
    8. デザインパターン
    9. フレームワーク
    10. ライブラリ
    11. Androidアプリケーション
    12. Project Jigsaw
    13. エラー一覧
    14. 日付の加算、減算
    15. 文字列の数字チェック
    16. 改行コードの削除
    17. 先頭と末端の文字の削除
    18. warファイルの中身を確認する方法
    19. nullもしくは空文字の判定
    20. beanの中身を確認する方法
    21. org.apache.log4j.Logger のログ出力で printStackTrace() のエラー内容を出力する方法
    22. Javaのバージョン確認方法