import宣言
Pageディレクティブのインポート属性を使って、外部クラスをインポートできます。
もちろん自分が作成したクラスもインポート可能ですが、クラスパスの通った場所に配置しておく必要があります。
web.xmlについて
web.xmlファイルは、Webアプリケーションの各種設定を記述するファイルで、作成するファイルで、作成する場所は__WEB-ENFの直下__でなければなりません。
<web-app>
<servlet>
<servlet-name>HellowServelet</servlet-name>
<servlet-class>common.Foward</servlet-class>
</servlet>
//servletタグは、サーブレットの登録。servlet-nameはmappinとも合わせる。サーブレットの名前。
//サーブレットのクラス名。パッケージがあればそこまで記載。
<servlet-mapping>
<servlet-name>HellowServelet</servlet-name>
<url-pattern>/HellowServelet</url-pattern>
</servlet-mapping>
//url-patternはブラウザから呼び出すURLのパターン
<servlet>
</web-app>
データを扱うためのクラス
サーブレットAPIでは、次のクラスで各スコープのデータを操作します。
スコープ | クラス |
---|---|
リクエスト | javax.servlet.http.HttpServletRequestインターフェイス |
セッション | javax.servlet.http.HttpSessionインターフェイス |
アプリケーション | javax.servlet.ServletContextインターフェイス |
これら3つのインターフェースでは、スコープのデータを操作するのに以下の様なメソッドを利用します。
メソッド | 説明 |
---|---|
Object getAttribute(String name) | 引数nameで指定したオブジェクトを取得する。存在しなかった場合はnullを返す。返ってきたオブジェクトはObeject型なので適切な値にキャストして利用することが多い |
void setAttribute(String name, Object value) | 引数valueで指定したオブジェクトをnameという名前で記録する |
void removeAttribute(String name) | 引数nameで指定したオブジェクトを削除する |
Enumeration getAttributeNames() | 登録されているnameの一覧を返す |
3つのクラスは共通のインターフェスなどは持ちませんが、メソッドのシグネチャは同じになっています。
また、各スコープに関連付けられているデータは__属性__(Attribute)とも呼ばれ、「リクエスト属性」「セッション属性」といういい方をします。このため、上の表のメソッド名はxxxAttributeという名前にんあtぅているのです。
※メソッドのシグネチャとは(メソッド名、引数の数、引数の型)
EL式
EL式(Expression Langage)は、JSP2.0で導入されたオブジェクトのアクセスを簡略化して記述できる式言語です。EL式は、${ ~ }タグを使用して記述します。
EL式は、静的HTMLの出力や、タグライブラリ、アクションの属性値として使用します。
EL式では、暗黙オブジェクトにアクセスできます。EL式の暗黙オブジェクトは、JSPの暗黙オブジェクトとは名前が異なるので注意して下さい。
xxxScopeという名前の暗黙オブジェクトは明示的にスコープを指定するのに利用できます。これらの暗黙オブジェクトはMap型なので、EL式を使って以下のように記述できます。
オブジェクトへのアクセス
スコープ変数へアクセスする例。スコープ変数とは、ページ、リクエスト、セッション、アプリケーションなどの属性にセットされたオブジェクトを表す変数のことです。サーブレットやスクリプトレットからは、このようなオブジェクトへは、getAttribute()
メソッドでアクセスしますが、ELでは、単純に(プロパティ名)でアクセスできます。
<%
request.setAttribute("message","hello2");
%>
${message}
${sessionScope.user}
この例では、セッションスコープからのみuserという名前のオブジェクトを取得し、他のスコープから不用意にオブジェクトを取得してくることはありません。
package sample.javaee.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/el-scope-servlet")
public class ELScopeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("hoge", "HOGE");
req.getSession().setAttribute("fuga", "FUGA");
req.getServletContext().setAttribute("piyo", "PIYO");
req.setAttribute("same", "RequestValue");
req.getSession().setAttribute("same", "SessionValue");
req.getServletContext().setAttribute("same", "ApplicationValue");
req.getRequestDispatcher("jsp/el4.jsp").forward(req, resp);
}
}
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>${requestScope.hoge} - ${sessionScope.fuga} - ${applicationScope.piyo}</h1>
<h2>${hoge} - ${fuga} - ${piyo}</h2>
<ul>
<li>${same}
<li>${requestScope.same}
<li>${sessionScope.same}
<li>${applicationScope.same}
</ul>
<% pageContext.setAttribute("same", "PageScopeValue"); %>
<h3>${same}</h3>
</body>
</html>
-
requestScope
、sessionScope
、applicationScope
は、それぞれHttpServletRequest
、HttpSession
、ServletContext
のsetAttribute()
にセットする。 - 各スコープに保存された値は、EL式上ではいきなりキーに指定した名前で参照できる。
- 異なるスコープに同じ名前で保存されている値をEL式で参照した場合、より狭いスコープで設定されている値が取得される。ページ>リクエスト>セッション>アプリケーションの順のページから優先される。
なお、ページスコープの暗黙オブジェクトはpage
ではなく、pageContext
です。
JavaBeansとプロパティ
プロパティ | ゲッタ | セッタ |
---|---|---|
String name | String getName() | void setName(String) |
boolean male | boolean isMale() | void setMale(boolean) |
ゲッタ、セッタでアクセスされる変数は、プロパティと呼ばれます。フィールド名とプロパティ名は同じ場合もおおいのですが、必ずしも同じとは限りません。たとえば以下の例ではprivateなフィールド変数の名前はfooですが、プロパティの名前はnameです。
public class User{
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(String name) {
this.foo = name;
}
}
また、セッタがなく、ゲッタだけがある場合は、読み取り専用のプロパティとなります。
次のコードは、Userクラスのプロパティにアクセスする例です。
<%
//準備
User user = new User();
user.setName("太郎");
user.setMale(true);
request.setAttribute("user", user);
%>
名前は${user.name}
男ですか${user.male}
ちなみに${user}
実行結果は
名前は太郎
男ですか? true
ちなみにel.User@64c5e2cf
次のEL式はuser変数のnameプロパティを評価しています。
${user.name}
細かくいうと次の処理が行われます。
- オブジェクトのスコープから"user"という名前のオブジェクトが取得されます。
この例ではリクエストスコープからUserクラスのインスタンスが取得されます。 - 取得されたオブジェクトの"name"プロパティが取得されます。
- 結果が出力されます。
このように__変数.プロパティ__という書式で、変数の示すオブジェクトのプロパティにアクセスすることが可能です。同等の処理をスクリプレットで書くと以下のようになります。
(正確にはUserへのキャストなどが必要)。
request.getAttribute("user").getName();
カスタムタグとJSTLについて
JSPの標準アクションは、よく利用される処理をタグの形で提供したものです。たとえばインクルード処理を行う場合、スクリプトレットでは次のようなコードになりますが、
<% request.getRequesetDispatcher("/page1.jsp").include(request, response); %>
これは標準アクションを使用することで、以下のように簡略化できます。
<jsp:include page="/page1.jsp" />
カスタムタグは、このようなタグによる処理の記述をユーザーが独自に定義できるようにしたものです。
ただし、多くのプロジェクトで必要とされる共通処理については、既に誰かが作成している場合が多いので、カスタムタグを一から作成している場合が多いので、カスタムタグを一から自作することは、実際の開発ではあまりないから一歩進んで「Javaの標準ライブラリ」に近い位置づけで利用できるようにしたのが__JSTL(JavaServer Pages Standard Tag Library)__です。
JSTLを動作させる
カスタムタグは通常、以下の2つのものをJARファイルにまとめた形で提供されています。
- タグのクラスファイル
- TLD(タグライブラリディスクリプタ)
上記のファイルを以下の手順でタグを利用します。
- JARファイルをクラスパスに配置する(WEB-INF/lib以下に置く)
- JSPでtaglib宣言を行い利用する
Coreタグの利用
JSTLは単一のカスタムタグライブラリではなく、複数のカスタムタグの集まりとして提供されています。
Coreタグの一覧(利用頻度が高いもの)
forEachタグ
<%
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list",list);
%>
<c:forEach var="item" items="${list}">
${item}
</c:forEach>
名前 | 必須 | リクエスト時 | 型 | 説明 |
---|---|---|---|---|
items | FALSE | TRUE | java.lang.Object | ループを行うコレクション |
var | FALSE | FALSE | java.lang.String | 取り出した要素を格納する変数の名前。子要素からアクセスできる |
※コレクション(collection)とは、収集(物)、所蔵品、堆積などの意味を持つ英単語。プログラミングの分野で、データやオブジェクトなどをまとめて格納するためのデータ構造。