スクリプティング要素って何?
式言語がJSP 2.0でJSPに取りいれられたことにより、機能的に重なる部分が多くなったため、式言語とスクリプティング要素のどちらを使用するかはプロジェクトの判断ということになっています。特に、式言語とスクリプティング要素の式はほぼ重なる部分のため、Aさんは式言語で、Bさんは式で記述すると、プロジェクト全体として統一がとれなくなり、保守性も乏しくなります。どちらを使用するかの判断はプロジェクトが始まる前の決定事項となります。
図1のJSPの構造で示した通り、スクリプティング要素は宣言、スクリプトレット、式から構成されます。スクリプティング要素で使用できる言語はJSP 2.1ではjavaのみです。JSP 2.1の仕様書の記述(「JSP.1.12 Scripting Elements」)にもあるように、他の言語の場合、意味論(semantics)の正確な定義はされていないようです。構文論(syntax)と意味論(semantics)はプログラム言語の基礎です。難しいとは思いますが、これらの意味を理解することは肝要です。
宣言
宣言はディレクティブで説明したように、変数とメソッドの宣言があります。
変数の宣言
変数の宣言の構文は次のようになります。
<%! int i = 0; %>
繰り返しになりますが、変数の宣言はフィールド変数の定義になるため、同期化には非常に注意しなければなりません。
メソッドの宣言
メソッドの宣言の構文は次のようになります。
<%! public boolean isAdult(int age) { booean adult = false; if (age >= 20) return true; } %>
変数の宣言同様、同期化には非常に注意しなければなりません。一般的にはServletのinitメソッドに相当するjspInitメソッドやServletのdestroyメソッドに相当するjspDestroyの定義に使用されることが多いようです。
スクリプトレット
スクリプトレットはpageディレクティブのlanguageで指定した言語を使用できます。JSP 2.1ではjavaのみ使用できるため、Javaでのコーディングとなります。スクリプトレットはテンプレート・テキストの中に自由に記述できます。以下がその例です。
<% if (age >= 20) {%> 成人 <% } else {%> 未成年 <% } %>
式
式は式言語でも説明したように値を返します。演算結果でも、オブジェクトの戻り値でも可能です。例えば、Employeeオブジェクトにnameプロパティがあり、setterメソッドが用意されている場合、次のように記述でき、その結果がクライアントに返されます。
<%= employee.getName() >
式言語と違う点は、式言語は翻訳時にStringに型変換してくれますが、式では型変換してくれません。リクエストがあった時点で、返される値がStringでない場合、ClassCastExceptionが発生します。上記の場合、式言語では${employee.name}のように書くことができます。この例では、String型を返すので有難みがありませんが、数値を返す場合など型変換してくれる方が楽ですし、リクエスト時にならないと例外が発生することが分からないということもありません。
アクションって何?
冒頭でJSPとはHTMLの仮面を被ったServletであると言いましたが、アクションはまさしくHTMLの仮面です。タグと言えばWebブラウザが読み込み処理するものですが、JSPのアクションも<jsp:XXX>という形をしており、一見HTMLのタグのように見えます。ところが形こそ似ているものの、アクションはサーバ側のJavaのロジックを呼び出すものであることを考えるとHTMLとは似ても似つかぬものであることが分かるはずです。
アクションにしろ、JSTLのようにJSPのタグライブラリにしろ、カスタムタグにしろ、タグはすべてJavaに置き換えられます。最終的にはHTMLという形でクライアントに情報が送られるわけですが、HTMLを自由に操り状況に応じて(コンテクストに応じて)柔軟なコンテンツを返すことができます。形はタグに似ていて名称がアクションということに違和感を覚えていた方も、サーバ側のロジックを起動するためのものと考えると違和感がなくなるかと思います。以下に、各アクションの説明を記載します。
<jsp:useBean>
<jsp:useBean>は、次のように記述します。
<jsp:useBean id="employee" class="jp.kawakubo.Employee" scope="session"/>
- JavaBeanとしてインスタンス化できない場合、classではなくtypeで指定します。抽象クラス、インターフェース、publicでもなくかつ引数が存在するコンストラクタを持つクラスの場合、typeで指定します。クラスが.serファイルに存在する場合、beanNameで指定します。class、type、beanNameを適切に指定しない場合、翻訳時に例外が発生します。
- scope属性を指定できます。値はapplication | session | request | pageのいずれかです。指定されたscopeでオブジェクトが見つからない場合、指定したクラスはインスタンス化されます(typeで指定した場合はインスタンス化されません)。
- jsp:useBeanアクションのbodyでjsp:setPropertyアクションを指定すると、クラスからインスタンス化する際、setPropertyで指定したプロパティに値が設定されます。
<jsp:setProperty>
- name属性はjsp:useBeanでインスタンス化したオブジェクトのid属性の値を指定します。従って、当アクションを記述する前にjsp:useBeanアクションを記述しなければなりません。
- property属性は文字通り、オブジェクトのsetterメソッドを持ったプロパティを指します。このプロパティに値を設定する場合、param属性かvalue属性のいずれかを指定します。param属性は名前の通りリクエスト(ServletRequest)のパラメータの値が設定され、value属性は文字通り値を指定します。従って、リテラル文字列やEL式を使って値を設定します。
<jsp:setProperty name="employee" property="*"/>のようにpropertyに*を指定すると、employeeオブジェクトに存在するプロパティと同じ名前のパラメータがある場合、その値が設定されます。一度に値を設定したい場合に便利です。propertyに*を設定する場合、パラメータから値を設定するため、param属性もvalue属性も不要です。
<jsp:getProperty>
- name属性はjsp:useBeanでインスタンス化したオブジェクトのid属性の値を指定します。
- property属性は文字通り、オブジェクトのgetterメソッドを持ったプロパティを指します。従って、このアクションは値を返します。
<jsp:include>
- page属性は外部から取り込むファイルをJSPからの相対パスで指定します。ファイルはHTMLやJSPを指定します。
- flush属性にtrueを指定すると、外部からファイルを取り込む時点でbufferの中を書きだすことができます。
- <jsp:param>をbodyに含めることで、取り込むファイルにパラメータを渡すことができます。
<jsp:forward>
- page属性は制御の転送先のJSPを相対パスで指定します。ServletからJSPへの制御の転送の仕方でも説明しますが、ServletのRequestDispatcherクラスのforwardメソッドに相応します。page属性の値はJSPからの相対パスで指定します。指定できるJSPは同じWebコンテナ上のJSPに限られます。
- <jsp:param>をbodyに含めることで、制御の転送先のJSPにパラメータを渡すことができます。
他にもアクションはありますが、上記のタグを押さえておけば入門段階では十分かと思われます。
