JSP関係でハマった問題とその解決方法を、書いていきます。
includeディレクティブとincludeアクションの違いを理解していなかっとことによる問題
問題
parent.jspにアクセスすると、以下のエラーが発生。
javax.servlet.ServletException: JSP ファイル "/grandchild.jsp" が見つかりません
parent.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<h1>Parent</h1>
<%@ include file="child.jsp" %>
child.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<h2>Child</h2>
<jsp:include page="grandchild.jsp" />
grandchild.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<h3>Parent</h3>
解決方法
-
parent.jsp内の、
<%@ include file="child.jsp" %>
を<jsp:include page="child.jsp" />
に置き換える。 -
child.jsp内の、
<jsp:include page="grandchild.jsp" />
を<%@ include file="grandchild.jsp" %>
に置き換える。
原因
includeディレクティブとincludeアクションの違いは次の通り。
- includeディレクティブは、Servletプログラムに変換する時点で組み込まれる。includeアクションはリクエストのあった時点で組み込まれる。
- includeディレクティブは、静的にリソースを組みこみ、組み込んだ側のJSPページと一体で処理される。includeアクションは処理された結果が、組み込まれる。
リソースが読み込まれる順番は次の通り、だと思う。
- parent.jspがアクセスされる。→ parent.jsp
- child.jspを静的にインクルードしようとするが、この時点でchild.jspにアクセスさらていないので、grandchild.jspをインクルードできない。
⇨エラー
終わりに
エラーが発生する原因は、インクルードの順番の問題だとは思うけど、いまいちうまく説明できなかった。
<c:import>
と<jsp:import>
が混在している場合も、上記のエラーが発生した。
原因は同様であると思うが、ちゃんと調査したい。
<c:import>
は<jsp:import>
よりパフォーマンスが最適かされているようなので、今後は<c:import>
を使っていきたい。
http://struts.wasureppoi.com/jstl/02_import.html