この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:7
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: JSP
SEOタイトル: JSP (JavaServer Pages) の構文と現代的な使い方(EL / JSTL / Thymeleaf 移行)

この記事の要点
  • JSP (JavaServer Pages) = HTML 内に Java を埋め込めるテンプレート。実態はServlet にコンパイルされる
  • 主な構文: <%@ page %> ディレクティブ、<%= expr %> 式、<% Java %> スクリプトレット
  • EL (Expression Language) ${user.name}JSTL / でスクリプトレット禁止が現代スタイル
  • Jakarta EE 10+ でパッケージが javax.servletjakarta.servlet に変更
  • 新規プロジェクトでは Thymeleaf 推奨。JSP は保守案件に残る程度の位置づけ

JSP とは

JSP (JavaServer Pages) は、HTML 内に Java コードや EL 式を埋め込んで動的ページを生成するサーバサイドテンプレート技術です。実行時にはサーブレットに変換され、JVM 上で動きます。Java EE (現 Jakarta EE)の標準仕様で、Servlet とセットで使われてきました。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


Hello JSP

    

Welcome, ${user.name}!

  • ${item.title} - ${item.price}円

主な構文要素

構文意味
<%@ page %>ページディレクティブ文字コード・import など
<%@ include %>静的 includeコンパイル時に取り込み
<%@ taglib %>タグライブラリ宣言JSTL / カスタムタグ
<%! ... %>宣言 (Servlet クラスのフィールド/メソッド)<%! int counter = 0; %>
<% ... %>スクリプトレット (Java 文)<% int n = 10; %>
<%= expr %>式 (出力)<%= user.getName() %>
<%-- comment --%>JSP コメント (出力されない)HTML コメント は出る
${expr}EL 式${user.name}
/ JSTL コアタグ条件分岐・繰り返し

ページディレクティブと文字コード

<%@ page language="java"
         contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"
         import="java.util.*, com.example.model.User"
         session="true"
         errorPage="/WEB-INF/error.jsp" %>

<%-- import を複数 --%>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Map" %>

<%-- 別ファイルを静的に取り込み (コンパイル時) --%>
<%@ include file="header.jsp" %>

<%-- 動的 include (実行時) --%>

スクリプトレットと式 (旧スタイル)

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="java.util.*" %>

<%-- 宣言: クラスのフィールドになる --%>
<%! private int hitCounter = 0; %>

<%-- スクリプトレット: _jspService メソッド内のローカル --%>
<%
    String name = (String) request.getAttribute("name");
    List items = (List) request.getAttribute("items");
    hitCounter++;
%>

Hello, <%= name %>

このページの表示回数: <%= hitCounter %>

    <% for (String item : items) { %>
  • <%= item %>
  • <% } %>
<%-- ❌ ロジックが散らかる。現代では避ける --%>

EL (Expression Language) と JSTL (推奨スタイル)

スクリプトレットを書かず、EL + JSTL で表現するのが現代の JSP の作法です。テンプレートとロジックを分離できます。

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ 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" %>

<%-- EL でリクエスト属性 / セッション / プロパティアクセス --%>

Hello, ${user.name}!

年齢: ${user.age}

住所: ${user.address.city}

<%-- 条件分岐 --%>

管理者です

大人 中高生 子供 <%-- 繰り返し --%>
  • ${s.count}: ${item.title} -
<%-- 関数 --%>

アイテム数: ${fn:length(items)}

大文字: ${fn:toUpperCase(user.name)}

<%-- 日付フォーマット --%>

登録日:

EL のスコープ参照

EL は名前の前に明示しなくても各スコープを順に探します(pageScope → requestScope → sessionScope → applicationScope):

<%-- 任意のスコープから自動探索 --%>
${user.name}

<%-- スコープ明示 --%>
${requestScope.user.name}
${sessionScope.cart.items}
${applicationScope.config.title}

<%-- リクエストパラメータ --%>
${param.q}                  <%-- ?q=xxx --%>
${paramValues.tags[0]}      <%-- 配列 --%>

<%-- Cookie / Header --%>
${cookie.JSESSIONID.value}
${header['User-Agent']}
${initParam.appName}        <%-- web.xml の init-param --%>

サーブレット側との連携

// MVC: Servlet がコントローラ、JSP がビュー
@WebServlet("/users")
public class UserListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        // モデル
        List users = userService.findAll();

        // リクエストスコープに格納
        req.setAttribute("users", users);
        req.setAttribute("title", "ユーザ一覧");

        // JSP に転送
        req.getRequestDispatcher("/WEB-INF/views/user-list.jsp")
           .forward(req, resp);
    }
}

カスタムタグ (Tag File)

<%-- /WEB-INF/tags/userCard.tag --%>
<%@ tag pageEncoding="UTF-8" %>
<%@ attribute name="user" required="true" type="com.example.User" %>

${user.name} ${user.email}
<%-- 使う側 --%>
<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>


    

Jakarta EE への移行

Jakarta EE 9(2020 年)から名前空間が javax.*jakarta.* に変わり、JSP は 3.0 → 3.1 になりました。Tomcat 10+ は jakarta 系のみ対応。

項目Java EE / Tomcat 9Jakarta EE / Tomcat 10+
パッケージjavax.servlet.*jakarta.servlet.*
JSTL taglib URIhttp://java.sun.com/jsp/jstl/corejakarta.tags.core
JSP 仕様2.33.1

Thymeleaf への移行が主流

Spring Boot 系で新規に JSP を採用する理由はほとんどありません。以下の理由で Thymeleaf が標準的に使われます:

  • JSP はSpring Boot の自動設定対象外(追加設定が必要)
  • JSP はブラウザで直接プレビューできない(独自タグでデザイナとの分業しづらい)
  • Thymeleaf は

    サンプル

    のようにHTML として有効
  • セキュリティ(XSS)デフォルト挙動が Thymeleaf の方が安全

FAQ

Q: スクリプトレットを禁止するには?
A: web.xmltrue を追加。チームの規約として強制できる。

Q: EL で出力すると XSS は大丈夫?
A: ${...}エスケープしない。安全に出すには または fn:escapeXml()

Q: JSP のホットリロード
A: Tomcat 等は JSP を変更すれば自動再コンパイル。本番では development=false でビルド時のみコンパイルにする方が高速。