Powered by SmartDoc

JavaBeans と JSP

JavaBeans とは何か

コンポーネント技法

機能別にまとめられ、コンパクトで再利用できるソフトウェア「部品」から、大規模なソフトウェアを構成しようという手法を「コンポーネント技法」と呼びます。

Javaのようなオブジェクト指向プログラミング言語では、もともと部品の再利用がやりやすくなっています。JavaBeansは、より明確にコンポーネント化を進めるために、いくつかのルールに従って作られているJavaのクラスです。

JavaBeans の特徴

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とプロパティ

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"を取り除いたもの )

整理すると、表4.1[プロパティと setter, getter]のようになります。

プロパティと setter, getter
プロパティ名 title
getter名 getTitle
setter名 setTitle

JavaBeans のサンプル

JavaBeansのサンプルを示しましょう。このBeanは、1冊の本のデータを示しています。引数無しのコンストラクタがあり、Serializableインタフェースを実装しています。また、ndcなどの6つのプロパティがあることもわかります。

BookData.java
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を呼び出す

JSPのページからBeanを呼び出すには、useBeanタグを利用します。このタグによって必要なBeanのインスタンスを生成して、指定した名前をつけることができます。JSPは、このインスタンスをスクリプトレットなどで利用するとともに、setProperty, getPropertyタグを使ってBeanのプロパティにアクセスできます。

jsp:useBean

Beanのインスタンスを作ります。

id属性はBeanの名前で、scope属性でBeanの寿命を示します。class属性ではBeanのパッケージ名を含めたクラス名を記述します。

<jsp:useBean id="today" scope="page"
	class="jp.ac.wakhok.tomoharu.Today" />

scopeはBeanの寿命を示すもので、次の4つのいずれかの値が入ります。

page
要求から応答の間
request
要求から応答の間(コンテナ内でデータのやり取りはできる)
session
セッションが有効である間
application
Webアプリケーションが動いている間

jsp:getProperty

Beanのyearプロパティの値を獲得しています。

   <jsp:getProperty name="today" property="year" />

jsp:setProperty

Beanのusernameプロパティに、"maruyama"という値を設定しています。

   <jsp:setProperty name="mybean" property="username" value="maruyama" />

JSP から Bean を利用するサンプル

JSPページ

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 のソース

Beanであるjp.ac.wakhok.tomoharu.Todayのソースを示します。JSPページのプロパティとの関係を読み取ってください。

Today.java
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 への配置

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