マークアップの合間に、動的なコンテンツを作成するためのロジックを表す特殊なJSP要素が含まれる
サーブレットに比べて、読みやすく?保守しやすく?単純である?ことから好まれる?
実際にはサーブレットテクノロジの拡張機能であり、JSPページは「JSP実装クラス」と呼ばれるJavaサーブレットに変換される(JSPエンジン)
JSPエンジンは、JSP実装クラスが存在しない、或いはJSPページより古い場合に起動する
JSPページ内で定義されているマークアップを出力するJavaコードと、ユーザーリクエストを処理する全てのコードを含む _jspService()メソッドが含まれる
Javaソースコードへの変換中にJSPページに不完全なJSP構成要素が含まれる場合、サーバーよりParseExceptionが返される
コンパイル中にスクリプトレットでの構文エラーが発生すると、サーバよりJasperExceptionが返される その場合実装クラス名とエラーのスタック情報が表示される
JSP実装クラスのインスタンスが存在しない場合、JSPコンテナはクラスの読込み・クラスのインスタンス化・jspInit()にて初期化処理が行われる
_jspService()メソッドを呼び出し、リクエストとレスポンスを渡してサービス処理を行う
JSP実装クラスの消滅により jspDestroy()にて消滅処理が行われる
重要な情報をJSPエンジンに渡すために使われる 出力は生成しない
include指令以外は、JSPページの先頭に記述しなければならない
<%@ 指令 {属性=”値”}* %>
<%@ page [ language="スクリプト言語" ] [ extends="パッケージ名.クラス名" ] [ import="インポートするパッケージ名" ] [ session="true | false" ] [ buffer="none | (size)kb" ] [ autoFlush="true | false" ] [ isThreadSafe="true | false" ] [ info="版権など" ] [ errorPage="対応しない例外が発生した場合のエラーページ" ] [ isErrorPage="true | false" ] [ contentType="MIMEタイプ" ] [ pageEncoding="peinfo" ] %>
errorPageは、JSPファイルのはじめに入れるべき
<%@ taglib uri="タグライブラリ" prefix="プレフィックス" %> taglibで登録したカスタムタグを使用できるようになる
JSPページ全体でのフィールド・メソッドを定義する
Java言語の予約語や暗黙的オブジェクト名をつけることはできない
<%! [宣言;]+ %>
マークアップの間に記述されるコードの断片 将来のJSP仕様ではJava以外の言語も記述できるようになるかもしれない
<% コード %>
String型かString型に変換できる肩でなければならない
<%= 式 %>
<jsp:include page="url" flush="true | false" /> JSPページなどほかのファイルを動的にインクルードする
<jsp:forward page="url" /> 別のJSPやサーブレットにフォアードし、呼出元のJSPページは処理を終了する
<jsp:plugin type="bean | applet" code="パッケージ名.クラス名" codebase="コードベース" [ align=/archive=/height=/hspace=/jreversion=/name=/vspace=/width=/nspluginurl=/iepluginurl= ] /> JavaアプレットまたはJavaBeansコンポーネントを組み込むことができ、ブラウザに適した<object>タグまたは<embed>タグを生成する <jsp:params>を含む場合は、内部にjsp:paramを列挙できる <jsp:fallback>を含む場合は、pluginが起動できない場合の代替コンテンツを指定できる コンテンツが見つからない場合はClassNotFoundExceptionとなる
<jsp:param name="name" value="value" /> jsp:include/forward/plugin と組み合わせて使用する
<jsp:useBean id="参照名" [scope="page | request | session | application"] typeSpec /> ボディをもつ場合、<jsp:setProperty>または、<%。。%>を含むことができる typeSpecでは、クラス名 | タイプ名 | クラス名+タイプ名 | ビーン名+タイプ名 の組み合わせが許される タイプ名としては、クラス名だけでなくスーパークラスや実装されたインターフェース名でも良い
<jsp:setProperty name="ビーン名" property="プロパティ名" value="<%=XX%>" />では、ビーンのsetterを呼ぶ
<jsp:getProperty name="ビーン名" property="プロパティ名" />は、getterを呼ぶがString型として出力される
パッケージ化されたpublic指定のシリアライズ可能クラスであり、publicの引数のないコンストラクタとsetter・getterのみをもつ
出力コメントは、レスポンスにて返される <!−− コメント −−> JSP式を含めても良い
JSPコメントは、レスポンスにて返されない <%−− コメント −−%> <% /*コメント*/ %>と同義
request=HttpServletRequest / response=HttpServletResponse / out=JspWriter / session=HttpSession / config=ServletConfig / application=ServletContext / page=Object(JSP実装クラス) / pageContext=Object(より抽象化された実装クラス) / exception=Throwable(エラーページの場合)
JSP標準で使用できるアクションとは別に、タグライブラリを参照することによりカスタムアクションを実行するためのタグ
カスタムタグの準備 タグハンドラの作成 → TLDファイルの作成 → web.xmlへのTLDファイルの登録 → JSPページ内にtaglib指令を記述 → カスタムタグをJSPページ内に記述 コンパイルは逆順で行われる
web.xml内<taglib>タグにて、taglib-uri/taglib-locationを指定する
taglib-locationは、TLDファイル(Tag Library Descripter)のコンテキストルートからのパスを指定する /WEB-INF以下の任意のディレクトリに配置するのが望ましい
URI・タグ名とそれを処理するタグハンドラクラス・属性がまとめられている
<taglib>がルートノードであり、tlib-version/jsp-version/short-name/tagを指定する
taglibタグ内<tag>タグは最低2つの要素が必要であり、name/tag-class/body-content/attributeを指定する
tagタグ内<body-content>タグには、empty/JSP/tagdependent(本文をもっても動的解釈されない)の3種の文字列を指定する
tagタグ内<attribute>タグには、name/required/rtexprvalueを指定し属性の設定を行う rtexprvalueをtrueで指定しないとJSP式を解釈しない
カスタムタグに関連付けられた実際のタグ処理を行うクラスファイル /WEB-INF以下classesかlibに配置する
javax.servlet.jsp.tagext.Tagインターフェース(doStartTag()/doEndTag())やIterationTagインターフェース(+doAfterBody())が大本であるが、本文をもつタグのためにはBodyTagインターフェース(+doInitBody()/setBodyContent())が使用される
実際には、IterationTagインターフェースを実装したTagSupportクラスとBodyTagインターフェースを実装したBodyTagSupportクラスのどちらかを継承してタグハンドラクラスを作成する
javax.servlet.jsp.tagext.TagSupportクラスを継承してタグを作成すると、本文をもたないタグや本文を解釈する必要のないタグを作成できる
doStartTag()の返り値として、SKIP_BODYまたはEVAL_BODY_INCLUDEを指定する EVAL_BODY_INCLUDEでは本文の評価・表示を行う
doEndTag()の返り値として、SKIP_PAGEまたはEVAL_PAGEを指定する SKIP_PAGEを指定するとタグより後の部分を評価しない
タグ属性値の扱いは、タグクラスのsetter/getterを作成する
doAfterBody()では、EVAL_BODY_AGAINかSKIP_BODYを指定でき、本文部分が再評価される
body-contentがJSPであれば、TagSupport.getParent()メソッドで上位タグハンドラクラスの参照を取得できる 下位の参照は取得できないがsetValue/getValueによりObject型の値を相互参照できる
同様にbody-contentがJSPであれば、findAncestorWithClass()メソッドでは、同JSPページに限定して上位タグを取得する getParent()ではさらに外部のJSPページを参照する可能性がある
TagSupportを継承したクラス doStartTag()の返り値として、EVAL_BODY_BUFFEREDが指定できるようになる この場合、本文の評価のみで表示は行わずにsetBodyContent()/doInitBody()に委ねる
メンバ変数bodyContentを利用または、setBodyContent(BodyContent bc)をオーバーライドすると、BodyContentオブジェクトを利用できる clearBody()メソッドでbodyContentをクリアできる
doInitBody()は、本文部分が評価される前に呼び出されるメソッドである
タグハンドラクラスにjavax.servlet.jsp.PageContextクラスを利用するためには、TagSupportクラスのメンバ変数であるpageContextを利用するか、setPageContext(PageContext pc)をオーバーライドする
pageContext.getOut()により、JspWriterオブジェクトを取得でき、JSPページへの出力を行うことができる
pageContext.getAttribute(name, scope)またはpageContext.findAttribute(name)を利用することで、JSPページからJavaBeansを受け取ることができる scopeは4つのスコープ全てが有効
pageContext.getRequest()/getSession()/getServletContext()メソッドにて、それぞれのスコープでのコンテキストを取得できる
JSP Standard Tag Libraryは、一般的に使用される標準的な処理をまとめたタグライブラリであり、core/I18N/sql/xmlがある