機能別にまとめられ、コンパクトで再利用できるソフトウェア「部品」から、大規模なソフトウェアを構成しようという手法を「コンポーネント技法」と呼びます。
Javaのようなオブジェクト指向プログラミング言語では、もともと部品の再利用がやりやすくなっています。JavaBeansは、より明確にコンポーネント化を進めるために、いくつかのルールに従って作られているJavaのクラスです。
JavaBeansは次のような特徴をもつJavaのクラスです。
Beanの属性を示します。これについては後述します。
Beanは、必要に応じてオブジェクトの状態を保存したり、復元したりすることができなければいけません。このことを、Beanを「永続化」する、といいます。このためには、Beanにjava.io.Serializableインタフェースを実装する必要があります。このインタフェースにはメソッドは定義されていないので、次のように定義するだけで構いません。
import java.io.Serializable; public class HogeBean implements Serializable { ..... ..... ..... }
Beanには引数無しのコンストラクタが必要です。
import java.io.Serializable; public class HogeBean implements Serializable { public HogeBean() { ..... ..... } ..... ..... }
もっとも、すべてのBeanがこれらの特徴を満たしているわけではありません。永続化が必要ないならば、Serializableインタフェースを実装しないこともあります。
JavaBeansは、「プロパティ」と呼ばれるものをもつJavaクラスです。あるBeanが持つ「属性」を「プロパティ」と考えることができます。例えば、「1冊の本」を示すBeanでは、次のようなプロパティが存在するでしょう。
Javaのクラスでは、クラスの属性は、クラス中のフィールドで表現されると考えられます。ところが、あるBeanが持つプロパティは、クラスのフィールドとは関係ありません。ある特定のネーミング・ルールに従ったメソッドの存在が、そのBeanのプロパティを決めているのです。
JavaBeansのネーミング・ルールでは、あるBeanに次のようなメソッドがあるとき、そのBeanにはtitleというプロパティが存在することになります。
String getTitle(); void setTitle(String title);
getTitleというメソッドは、titleというプロパティの値を獲得するメソッドです。このメソッドを"getter"と言います。また、setTitleというメソッドは、titleというプロパティに値を設定するメソッドです。このメソッドを"setter"と言います。
setter、getterとプロパティのネーミング・ルールは、次のように整理できます。getterは、"get"で始まる名前を持つメソッドで、setterは、"set"で始まる名前を持つメソッドです。"set","get"の後に続く文字列が、プロパティの名前に対応します。正確には、プロパティ名の先頭の文字を大文字にして、"set"や"get"の文字を加えたものが、setterとgetterになります。
setter名 = "set" + ( プロパティ名 )' getter名 = "get" + ( プロパティ名 )'
逆に言うとプロパティ名は、setter名やgetter名から、先頭の"set"、"get"を取り除いた文字列に対応します。
プロパティ名 = ( setter名から、先頭の"set"を取り除いたもの ) プロパティ名 = ( getter名から、先頭の"get"を取り除いたもの )
整理すると、表8.2.1[プロパティと setter, getter]のようになります。
プロパティ名 | title |
getter名 | getTitle |
setter名 | setTitle |
JavaBeansのサンプルを示しましょう。このBeanは、1冊の本のデータを示しています。引数無しのコンストラクタがあり、Serializableインタフェースを実装しています。また、ndcなどの6つのプロパティがあることもわかります。
package jp.ac.wakhok.library; import java.io.Serializable; public class BookData implements Serializable { private String ndc; private String tyosya_hyouji; private String id; private String title; private String author; private String publisher; public BookData() { ndc = ""; tyosya_hyouji = ""; id = ""; title = ""; author = ""; publisher = ""; } public String getNdc() { return ndc; } public void setNdc(String ndc) { this.ndc = ndc; } public String getTyosya_hyouji() { return tyosya_hyouji; } public void setTyosya_hyouji(String tyosya_hyouji) { this.tyosya_hyouji = tyosya_hyouji; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } }
JSPのページからBeanを呼び出すには、useBeanタグを利用します。このタグによって必要なBeanのインスタンスを生成して、指定した名前をつけることができます。JSPは、このインスタンスをスクリプトレットなどで利用するとともに、setProperty, getPropertyタグを使ってBeanのプロパティにアクセスできます。
Beanのインスタンスを作ります。
id属性はBeanの名前で、scope属性でBeanの寿命を示します。class属性ではBeanのパッケージ名を含めたクラス名を記述します。
<jsp:useBean id="today" scope="page" class="jp.ac.wakhok.tomoharu.Today" />
scopeはBeanの寿命を示すもので、次の4つのいずれかの値が入ります。
Beanのyearプロパティの値を獲得しています。
<jsp:getProperty name="today" property="year" />
Beanのusernameプロパティに、"maruyama"という値を設定しています。
<jsp:setProperty name="mybean" property="username" value="maruyama" />
JSPからBeanを利用するサンプルを見てみましょう。ここでは、jp.ac.wakhok.tomoharu.TodayというBeanから、todayという名前のインスタンスが作られています。しかしここで大事なのは、このオブジェクトやそのメソッドではなく、このオブジェクトがyear, month, date, hour, minuteといった「プロパティ」を持つことです。このJSPページでは、これらのプロパティが、getPropertyタグで文字列として取り出されています。
<%@ page contentType="text/html; charset=Shift_JIS" %> <jsp:useBean id="today" scope="page" class="jp.ac.wakhok.tomoharu.Today" /> <html> <head> <title>現在の日時を表示します</title> </head> <body> <h1>現在の日時を表示します</h1> <hr> <ul> <li>年: <jsp:getProperty name="today" property="year" /> <li>月: <jsp:getProperty name="today" property="month" /> <li>日: <jsp:getProperty name="today" property="date" /> <li>時: <jsp:getProperty name="today" property="hour" /> <li>分: <jsp:getProperty name="today" property="minute" /> </ul> </body> </html>
このJSPページからの出力は、次のようになります。
* 年: 2003 * 月: May * 日: 13 * 時: 13 * 分: 51
JSPを記述する人は、Beanのプロパティにアクセスするタグを書くだけでよく、スクリプトレットを書かなくても済みます。
Beanであるjp.ac.wakhok.tomoharu.Todayのソースを示します。JSPページのプロパティとの関係を読み取ってください。
package jp.ac.wakhok.tomoharu; import java.util.Calendar; import java.util.Date; import java.io.Serializable; public class Today implements Serializable { private Calendar calendar; public Today() { calendar = Calendar.getInstance(); Date d = new Date(); calendar.setTime(d); } public int getYear() { return calendar.get(Calendar.YEAR); } public String getMonth() { int m = calendar.get(Calendar.MONTH); String[] months = new String [] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; return months[m]; } public int getDate() { return calendar.get(Calendar.DATE); } public int getHour() { return calendar.get(Calendar.HOUR_OF_DAY); } public int getMinute() { return calendar.get(Calendar.MINUTE); } public static void main(String args[]) { Today today = new Today(); System.out.println("年: " + today.getYear()); System.out.println("月: " + today.getMonth()); System.out.println("日: " + today.getDate()); System.out.println("時: " + today.getHour()); System.out.println("分: " + today.getMinute()); } }
Tomcatをインストールしているディレクトリを%CATALINA_HOME%とします。%CATALINA_HOME%/testディレクトリがあるなら、その中のWEB-INF/classesディレクトリにBeanを配置します。
ここで気をつけなければいけないのは、Beanはパッケージに含まれている必要があるということです。Beanのパッケージ名に合わせてフォルダを作り、その中にBeanを配置します。この例のように、Beanがjp.ac.wakhok.tomoharuパッケージに属しているなら、WEB-INF/classes/jp/ac/wakhok/tomoharuにToday.classを配置します。
%CATALINA_HOME% -- webapps/ -- test/ | |-- WEB-INF/ --- web.xml | |- classes/ | |- lib/ |-- loop.jsp