サーブレット&JSPの基本|静的インクルード

実行前にJSPの内容を取り込む。静的インクルードで共通設定や変数をまとめて利用しよう

前回は、jsp:includeを使った動的インクルードについて学習しました。

動的インクルードは、JSPファイルの実行中に別のJSPファイルを呼び出し、そのJSPが出力した結果を現在の画面に取り込むしくみでした。

たとえば、共通フッターをsiteFooter.jspとして用意しておき、複数のJSPからjsp:includeで取り込むと、フッター部分を1か所で管理できます。

今回学習するのは、もう1つのインクルードである静的インクルードです。

静的インクルードは、JSPファイルを実行する前に、別のJSPファイルの内容そのものを取り込むしくみです。

動的インクルードが実行中に出力結果を取り込むのに対して、静的インクルードは実行前にファイルの中身を取り込みます。

この違いはとても大切です。

静的インクルードでは、インクルード対象のJSPに書かれているpageディレクティブ、import、変数宣言などを、インクルード元のJSPでも利用できます。

たとえば、共通で使うimport文や、画面で使う共通の変数をcommon.jspにまとめておき、それを別のJSPから静的インクルードすることができます。

この記事では、静的インクルードの基本、includeディレクティブの書き方、動的インクルードとの違い、JSPファイル更新時の注意点を、サンプルを使いながら丁寧に確認していきます。

静的インクルードとは

静的インクルードとは、JSPファイルの実行前に、別のJSPファイルの内容を取り込むしくみです。

静的インクルードには、includeディレクティブを使います。

書き方は、pageディレクティブに似ています。

<%@ include file="インクルード対象" %>

file属性には、取り込みたいJSPファイルを指定します。

この指定は、インクルード元JSPファイルのディレクトリを起点とした相対パスです。

たとえば、includeStatic.jspとcommonInfo.jspが同じsrc/main/webappディレクトリにある場合は、次のように指定できます。

<%@ include file="commonInfo.jsp" %>

静的インクルードでは、commonInfo.jspの出力結果ではなく、commonInfo.jspに書かれた内容そのものがincludeStatic.jspに取り込まれます。

動的インクルードとの違い

静的インクルードを理解するには、前回学習した動的インクルードとの違いを押さえることが大切です。

動的インクルードでは、JSPの実行中に別のJSPを実行し、その出力結果を取り込みます。

一方、静的インクルードでは、JSPが実行される前に、別のJSPファイルの内容そのものを取り込みます。

動的インクルードと静的インクルードの違い

種類取り込むもの取り込むタイミング主な使い方
動的インクルードインクルード対象の出力結果JSPの実行中ヘッダーやフッターなどの画面部品を取り込む
静的インクルードインクルード対象のファイル内容JSPの実行前共通のimport、変数、宣言、設定などを取り込む

動的インクルードは、別のJSPを実行して、その結果を現在の画面に差し込むイメージです。

静的インクルードは、JSPファイルを1つに結合してから実行するイメージです。

この違いにより、静的インクルードでは、インクルード対象に書かれている変数やimportを、インクルード元で利用できます。

図1:静的インクルードは実行前に内容を取り込む

この図から分かること

静的インクルードでは、JSPが実行される前に、インクルード対象のJSPファイルの内容が取り込まれます。

そのため、インクルード対象に書かれているimportや変数を、インクルード元のJSPで利用できます。

これは、動的インクルードとは大きく異なる点です。

動的インクルードでは、インクルード対象の出力結果を取り込みます。一方、静的インクルードでは、ファイルの中身そのものを取り込んでからJSPとして処理されます。

includeディレクティブを使う

静的インクルードでは、includeディレクティブを使います。

ディレクティブとは、JSP全体に関する指示を書くための要素です。

pageディレクティブでは、文字コードやimportなどを指定しました。

includeディレクティブでは、別のファイルを取り込む指示を書きます。

includeディレクティブの基本

項目内容
使用する要素includeディレクティブ
指定する属性file属性
取り込むものインクルード対象JSPの内容
パスの基準インクルード元JSPファイルのディレクトリ

includeディレクティブは、次のように書きます。

<%@ include file="インクルード対象" %>

file属性には、取り込みたいJSPファイルを指定します。

同じディレクトリにあるJSPを取り込む場合は、ファイル名だけで指定できます。

静的インクルードで利用できるもの

静的インクルードでは、インクルード対象のファイル内容が実行前に取り込まれます。

そのため、インクルード対象に書かれている内容を、インクルード元で利用できます。

静的インクルードで利用しやすいもの

内容説明
importしたクラスcommonInfo.jspでimportしたクラスをインクルード元で使える
変数commonInfo.jspで定義した変数をインクルード元で使える
宣言共通で使う宣言をまとめられる
taglibディレクティブ共通で使うタグライブラリの指定をまとめられる

たとえば、commonInfo.jspでLocalDateとDateTimeFormatterをimportしておけば、includeStatic.jsp側でそれらのクラスを使えます。

また、commonInfo.jspでString learnerNameという変数を用意しておけば、includeStatic.jsp側でlearnerNameを表示できます。

静的インクルードを行うJSPファイルの例

ここでは、学習メモサイトの今日の学習メッセージを表示するJSPを作成します。

includeStatic.jspでは、commonInfo.jspを静的インクルードします。

commonInfo.jspには、日付を扱うためのimportと、表示に使う学習者名を用意します。

includeStatic.jspでは、commonInfo.jspでimportしたLocalDateとDateTimeFormatterを使って今日の日付を作成します。

さらに、commonInfo.jspで定義したlearnerNameを使って、画面に学習メッセージを表示します。

ファイル名: includeStatic.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%@ include file="commonInfo.jsp" %>
<%
LocalDate date = LocalDate.now();
DateTimeFormatter formatter =
        DateTimeFormatter.ofPattern("MM月dd日");
String today = date.format(formatter);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>静的インクルードによる学習メッセージ</title>
</head>
<body>
<h1>今日の学習メッセージ</h1>
<p><%= learnerName %>さんの<%= today %>の学習テーマは、ServletとJSPの復習です。</p>
<p>共通情報を静的インクルードで取り込むことで、JSP内の設定や変数をまとめて管理できます。</p>
</body>
</html>

includeStatic.jspは、src/main/webappディレクトリに作成します。

このJSPがインクルード元です。

2行目でincludeディレクティブを使い、commonInfo.jspを静的インクルードしています。

そのため、commonInfo.jspでimportしたLocalDateとDateTimeFormatterを、includeStatic.jsp内でそのまま利用できます。

また、commonInfo.jspで定義したlearnerNameも、includeStatic.jsp内で表示できます。

静的インクルードで取り込まれるJSPファイルの例

次に、includeStatic.jspから取り込まれるcommonInfo.jspを作成します。

commonInfo.jspには、日付処理で使うクラスのimportと、学習者名を表す変数を用意します。

ファイル名: commonInfo.jsp

<%@ page language="java" pageEncoding="UTF-8" %>
<%@ page import="java.time.LocalDate,
    java.time.format.DateTimeFormatter" %>
<% String learnerName = "山田 太郎"; %>

commonInfo.jspも、src/main/webappディレクトリに作成します。

このJSPは、単独で画面全体を表示するためのファイルではありません。

includeStatic.jspから静的インクルードされ、共通のimportや変数を提供するためのファイルです。

そのため、html、head、bodyなどの画面全体の構造は書いていません。

また、commonInfo.jspではcontentType属性を指定していません。

画面としてHTMLを出力する中心はincludeStatic.jspなので、commonInfo.jspでは文字コードに関係するpageEncodingを指定し、共通情報をまとめる役割にしています。

図2:commonInfo.jspの内容をincludeStatic.jspで利用する

この図から分かること

commonInfo.jspには、LocalDateやDateTimeFormatterのimport、そしてlearnerNameという変数が書かれています。

includeStatic.jspでcommonInfo.jspを静的インクルードすると、commonInfo.jspの内容が実行前に取り込まれます。

そのため、includeStatic.jspでは、commonInfo.jspでimportしたクラスや定義した変数を利用できます。

動的インクルードでは、インクルード対象の出力結果を取り込むだけなので、このような使い方はできません。

includeStatic.jspの処理の流れ

includeStatic.jspでは、まずpageディレクティブでJSPの基本設定を行っています。

その次に、includeディレクティブでcommonInfo.jspを取り込んでいます。

includeStatic.jspで行っていること

順番処理内容
1pageディレクティブを書くcontentTypeやpageEncodingを指定する
2includeディレクティブを書くcommonInfo.jspの内容を取り込む
3LocalDate.nowを使う今日の日付を取得する
4DateTimeFormatterを使う日付をMM月dd日の形式に整える
5learnerNameを使う学習者名を画面に表示する
6HTMLを出力するブラウザに学習メッセージを表示する

ここで大切なのは、LocalDate、DateTimeFormatter、learnerNameがincludeStatic.jsp側に直接書かれていない点です。

これらはcommonInfo.jspに書かれています。

それでもincludeStatic.jspで利用できるのは、静的インクルードによってcommonInfo.jspの内容が実行前に取り込まれるためです。

commonInfo.jspにcontentType属性を書かない理由

commonInfo.jspは、画面全体を直接表示するJSPではありません。

includeStatic.jspに取り込まれて使われる共通部品のようなファイルです。

そのため、commonInfo.jspではcontentType属性を指定していません。

commonInfo.jspの役割

項目内容
直接表示する画面かいいえ
HTML全体を書くか書かない
共通のimportを書くか書く
共通の変数を書くか書く
contentType属性基本的には不要

contentType属性は、ブラウザへ返すレスポンスの種類や文字コードを指定するために使います。

画面全体を出力する中心のJSPでは必要になりますが、静的インクルードされる共通情報用のJSPでは、必ずしも指定する必要はありません。

動作確認の手順

includeStatic.jspとcommonInfo.jspを作成したら、ブラウザで動作を確認します。

プロジェクト名はstudyなので、URLは次のようになります。

http://localhost:8080/study/includeStatic.jsp

確認手順

手順内容
1動的Webプロジェクトstudyを作成する
2src/main/webappにincludeStatic.jspを作成する
3src/main/webappにcommonInfo.jspを作成する
4studyをTomcat11_Java25に追加する
5サーバを起動する
6ブラウザでhttp://localhost:8080/study/includeStatic.jspへアクセスする
7今日の学習メッセージが表示されることを確認する
8山田 太郎さんの今日の日付入りメッセージが表示されることを確認する

画面に学習者名と日付が表示されれば、commonInfo.jspで定義した内容をincludeStatic.jspで利用できています。

ブラウザの表示例

commonInfo.jspを変更したときの注意点

静的インクルードでは、インクルード対象のJSPファイルの内容を実行前に取り込みます。

そのため、インクルード対象であるcommonInfo.jspを変更したときは、表示結果への反映に注意が必要です。

たとえば、commonInfo.jspのlearnerNameを次のように変更したとします。

山田 太郎 から 青山 花子 に変更する

変更後にブラウザを更新しても、環境によっては表示がすぐに変わらないことがあります。

これは、JSPが一度サーブレットに変換され、インスタンス化されたあと、そのインスタンスが再利用されるためです。

静的インクルードでは、commonInfo.jspの内容がincludeStatic.jspに取り込まれた状態で処理されます。

そのため、commonInfo.jspだけを変更しても、インクルード元であるincludeStatic.jspが再コンパイルされない場合、古い内容が使われ続けることがあります。

インクルード元のJSPも更新が必要になることがある

静的インクルードで取り込まれるJSPを変更した場合、インクルード元のJSPも更新する必要がある場合があります。

更新時の注意

変更したファイル反映されるために必要なこと
includeStatic.jspincludeStatic.jsp自体が更新されるため反映されやすい
commonInfo.jsp環境によってはincludeStatic.jspの再コンパイルが必要
両方を更新変更が反映されやすい

静的インクルードは、実行前にファイル内容を取り込むしくみです。

そのため、インクルード対象を変更したら、インクルード元にも影響があると考える必要があります。

もし変更が反映されない場合は、includeStatic.jspを保存し直す、サーバを再起動する、プロジェクトをクリーンするなどの方法で確認します。

図3:静的インクルードでは更新反映に注意する

この図から分かること

静的インクルードでは、インクルード対象のファイル内容がインクルード元に取り込まれた状態で処理されます。

そのため、commonInfo.jspを変更しても、includeStatic.jspが再コンパイルされない場合、古い内容が表示され続けることがあります。

変更が反映されないときは、インクルード元のJSPを保存し直す、サーバを再起動する、プロジェクトをクリーンするなどの確認が必要です。

ただし、Tomcatのように、インクルード対象のJSP更新を検知して、インクルード元を自動で再コンパイルしてくれる環境もあります。この動作はアプリケーションサーバによって異なるため、利用する環境で確認しておきましょう。

静的インクルードでできること

静的インクルードは、インクルード対象の内容を取り込むため、次のような用途に向いています。

静的インクルードに向いている内容

用途内容
共通のimport複数JSPで使うクラスのimportをまとめる
共通変数複数JSPで使う簡単な変数をまとめる
共通宣言複数JSPで使う宣言をまとめる
taglibディレクティブ複数JSPで使うタグライブラリ指定をまとめる

ただし、何でも静的インクルードにまとめればよいわけではありません。

画面に表示する共通部品を取り込むだけなら、動的インクルードのほうが分かりやすい場合もあります。

静的インクルードは、実行前に内容を取り込むという性質を理解したうえで使うことが大切です。

動的インクルードと静的インクルードの使い分け

動的インクルードと静的インクルードは、どちらも別のJSPを取り込むためのしくみです。

ただし、取り込む対象とタイミングが異なります。

使い分けの目安

目的向いている方法
共通フッターの出力結果を取り込みたい動的インクルード
共通ヘッダーの出力結果を取り込みたい動的インクルード
共通のimportをまとめたい静的インクルード
共通の変数や宣言を使いたい静的インクルード
インクルード対象の出力だけが必要動的インクルード
インクルード対象に書いた内容をインクルード元で使いたい静的インクルード

動的インクルードは、画面部品の出力結果を取り込むときに向いています。

静的インクルードは、JSPの内容そのものを取り込んで、インクルード元で利用したいときに向いています。

静的インクルードを使うときに意識したいこと

静的インクルードを使うと、共通のimportや変数をまとめられるため便利です。

しかし、インクルード対象の内容がそのまま取り込まれるため、変数名の重複や更新反映には注意が必要です。

注意したいポイント

ポイント内容
変数名の重複に注意するインクルード元と対象で同じ変数名を使うとエラーや混乱の原因になる
パス指定に注意するインクルード元から見た相対パスで指定する
更新反映に注意するインクルード対象を変更したら、インクルード元の再コンパイルが必要な場合がある
用途を分ける出力結果を取り込みたいだけなら動的インクルードも検討する

静的インクルードは、JSPを実行する前にファイル内容を取り込むため、便利な一方で影響範囲が広くなりやすい特徴があります。

共通情報をまとめるときは、何をどのJSPで定義しているのかが分かるように、ファイル名や変数名を整理しておきましょう。

静的インクルードで押さえたいポイント

静的インクルードは、includeディレクティブを使って別のJSPファイルの内容を取り込む方法です。

動的インクルードが実行中に出力結果を取り込むのに対し、静的インクルードは実行前にファイル内容を取り込みます。

そのため、インクルード対象でimportしたクラスや、定義した変数を、インクルード元で利用できます。

書き方は、<%@ include file="インクルード対象" %>です。

file属性には、インクルード元JSPファイルのディレクトリを起点とした相対パスを指定します。

静的インクルードは便利ですが、インクルード対象を変更したときに、インクルード元の再コンパイルが必要になる場合があります。

Tomcatのように自動で再コンパイルしてくれる環境もありますが、アプリケーションサーバによって動作が異なることがあるため、変更が反映されない場合はサーバ再起動やプロジェクトのクリーンも確認しましょう。