JavaでHello World
Google
  HOME  |  基礎  |  掲示板  |  ツール |  書籍  |  デザインパターン  |  リンク  |  フィードバック
JavaでHello World > JSP(カスタムタグ)編  
メニュー
Home
情報交換掲示板
ツールの部屋
Java関連の書籍
アプリケーション編
Swing編
Swing(イベント)編
Swing(Look&Feel)編
アプレット編
iアプリ編
サーブレット編
サーブレット(Linux)編
サーブレット(web.xml)編
サーブレット(セッション)編
サーブレット(クッキー)編
サーブレット(フィルタ)編
JSP編
JSP(ディレクティブ)編
JSP(アクション)編
JSP(スクリプト)編
JSP(オブジェクト)編
JSP(カスタムタグ)編
JSP(データベース)編
Apache + Tomcat編
Struts編
JDBC編
JDBC(データソース)編
JDBC(MySQL)編
JDBC(PostgreSQL)編
JDBC(トランザクション)編
JavaMail(SMTP)編
JavaMail(POP)編
JNI編
RMI編
RMI(アプレット)編
CORBA編
JNDI編
EJB編
EJB(Entity Bean)編
JMS(PTP)編
JMS(Pub/Sub)編
XML(SAX)編
XML(DOM)編
XSLT編
SOAP編
国際化編
国際化(タイムゾーン)編
国際化(通貨)編
リフレクション編
コレクション編
コレクション(Set)編
コレクション(List)編
コレクション(Map)編
スレッド編
正規表現編
アサーション編
ログ機能編
サウンド編
ファイル入出力編
URL編
ソケット編
データグラム編
HTTP
FTP編
jar編
javadoc編
Ant編
外部コマンド編
プロパティファイル編
システムプロパティ編
Eclipse編
  2002/02/03  田中宏和
Last Update 2003/01/29
JSP(カスタムタグ)編
◆カスタムタグとは?
JSPで自分で作ったタグの動作を定義できる機能です。
◆ここでの環境
OS Windows XP
J2SE SDK 1.4.1_01
サーバー Tomcat4.1.18
◆Tomcatを使用可能にする
サーブレット編を参考にしてTomcatを使用可能にしてください。
◆ボディがある場合とない場合の2種類のタグがあります
ボディありのタグとは下のようにタグの中になんらかの記述がある場合です。
<hw:helloworld>
ここがボディの記述
</hw:helloword>
ボディなしのタグとは下のようなタグのことです。
<hw:helloworld/>
 
タグハンドラ(ボディが無い場合)の作成
タグハンドラを作成します。タグハンドラとはタグを処理するクラスのことです。
タグハンドラはTagインターフェースまたはBodyTagインターフェースを実装(implements)しなければなりません。ボディを処理しない場合またはボディがない場合はTagインターフェース、ボディを処理する場合はBodyTagインターフェースを実装(implements)します。実際にはタグハンドラはTagインターフェースを実装(implements)したTagSupportクラス、またはBodyTagインターフェースを実装(implements)したBodyTagSupportクラスを継承(extends)すればいいようになっています。
ボディの有無 インターフェース クラス
無し Tag TagSupport
有り BodyTag BodyTagSupport
◆ここで使用するファイル
HelloWorldTag.java タグハンドラ
(タグ名:helloworld)
helloworld.tld タグライブラリディスクリプタ
hellowroldtag.jsp JSPファイル
◆タグハンドラ(ボディが無い場合)のコード
HelloWorldTag.java(ここからダウンロード)
package javahello;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class HelloWorldTag extends TagSupport {
  public int doStartTag() throws JspException {
    try {
      // Hello Worldと出力
      pageContext.getOut().print("Hello World");
    } catch (Exception e) {
      throw new JspException(e.getMessage());
    }
    return SKIP_BODY;
  }

  public int doEndTag() {
    return EVAL_PAGE;
  }
}
 
■メソッドの説明
メソッド 説明
doStartTag() 開始タグを処理するメソッド
doEndTag() 終了タグを処理するメソッド
■メソッドの戻り値の説明
メソッド 戻り値 説明
doStartTag() SKIP_BODY ボディをJSPとして評価しない場合
EVAL_BODY_INCLUDE ボディをJSPとして評価する場合
doEndTag() SKIP_PAGE
終了タグ以降のJSPを評価しない
EVAL_PAGE
終了タグ以降のJSPを評価する
◆タグハンドラのコンパイル
タグハンドラをコンパイルするにはservlet.jarをクラスパスに追加する必要があります。servlet.jarはTomcatのフォルダの下のcommon\libの下に入っています。(CLASSPATHへの追加方法はアプリケーション編を参考にしてください。
コマンドプロンプト
C:\作業フォルダ\JavaHello>javac HelloWorldTag.java

C:\作業フォルダ\JavaHello>

◆タグディスクリプタライブラリファイルの作成
タグディスクリプタライブラリファイルを作成します。タグディスクリプタライブラリファイルとはタグに関する情報を記述してあるXML形式のファイルです。
helloworld.tld(ここからダウンロード)
<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

<taglib>
  <tlibversion>1.0</tlibversion>
  <jspversion>1.1</jspversion>
  <shortname>javahello</shortname>
  <info>JavaでHello World タグライブラリ</info>

  <tag>
    <name>helloworld</name>
    <tagclass>javahello.HelloWorldTag</tagclass>
    <bodycontent>empty</bodycontent>
    <info>Hello Worldと出力</info>
  </tag>

</taglib>

 
■タグディスクリプタのタグの説明
このタグライブラリに関する情報<taglib>〜</taglib>
タグ 説明
tlibversion このタグライブラリのバージョン
jspversion 使用するJSPのバージョン(optional)
shortname このタグライブラリの短縮名
uri このタグライブラリのURIを指定(optional)
info このタグライブラリの説明(optional)
tag タグに関する情報。1つ以上記述。(下記 タグに関する情報を参照)
タグに関する情報<tag>〜</tag>
タグ 説明
name タグ名
tagclass このタグを処理するタグハンドラクラスの完全修飾パッケージ名を指定。
teiclass TEIクラスの完全修飾パッケージ名を指定。(optional)
bodycontent ボディの内容のタイプを指定
以下の3つを指定可能
tagdependent・・・ボディがSQL文などのJSP以外の記述である場合。
JSP・・・ボディがJSPの構文を含んでいる場合。
empty・・・ボディが無い場合
info このタグの説明(optional)
attribute タグが属性を持つ場合、その属性情報を指定(下記 タグの属性に関する情報を参照)
タグの属性に関する情報<attribute>〜</attribute>
タグ 説明
name タグの属性名
required この属性が必ず必要か、任意かを指定。この要素を指定しない場合はfalseを指定したと同じになる。(optional)
true,false,yes,noを指定可能
rtexprvalue 属性の値の指定がJSPのスクリプトであるかないかを指定。この要素を指定しない場合はfalseを指定したと同じになる。(optional)
true,false,yes,noを指定可能
例)
trueまたはyesの場合
</hw:helloworld id="<%=id %>">
上記のように属性の値を指定可能。
optional・・・省略可能
◆JSPコード
helloworldtag.jsp(ここからダウンロード)
<%@ page contentType="text/html; charset=Shift_JIS" %>
<%@ page import="javahello.HelloWorldTag" %>
<%@ taglib uri="/jsp/helloworld.tld" prefix="hw" %>
<html>
<head>
<title>Hello World Jsp Custom Tag</title>
</head>
<body>
<hw:helloworld />
</body>
</html>
 
 
◆TomcatへのファイルのコピーとTomcatの再起動
これで必要なファイルが全て整いました。Tomcatで見れるようにするためにファイルをコピーします。Tomcatのフォルダ\webapps\examples\WEB-INF\classes\javahelloフォルダを作成してください。

HelloWorldTag.class → Tomcatのフォルダ\webapps\examples\WEB-INF\classes\javahello
helloworld.tld → Tomcatのフォルダ\webapps\examples\jsp
helloworldtag.jsp → Tomcatのフォルダ\webapps\examples\jsp

コピーできましたらTomcatを再起動しましょう。
◆ブラウザーで見てみよう!
以下のURLを指定してブラウザで見てみましょう。
http://localhost:8080/examples/jsp/helloworldtag.jsp
おおおお!表示されましたね!
 
タグハンドラ(ボディが有る場合)の作成
次にボディがある場合に挑戦してみましょう。ここではJDBCでデータベースに接続して結果を表示するタグを作ります。
◆ここで使用するファイル
HelloWorldQueryTag.java データベースに接続して結果セットを得るタグハンドラ
(タグ名:query)
HelloWorldBodyTag.java 検索結果を表示するタグハンドラ
(タグ名:foreach)
HelloWorldBodyTEI.java foreachタグのTEIクラス
helloworld.tld タグライブラリディスクリプタ
hellowroldbodytag.jsp JSPファイル
◆タグハンドラ(ボディが有る場合)のコード
■データベースに接続して結果セットを得るタグハンドラ(タグ名:query)
HelloWorldQueryTag.java(ここからダウンロード)
package javahello;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;

public class HelloWorldQueryTag extends BodyTagSupport {
  String url;
  String jdbcClass;
  String userName;
  String passwd;

  Connection con;
  Statement stmt;


  public void setUrl(String url) {
    this.url = url;
  }
  public String getUrl() {
    return url;
  }
  public void setJdbcClass(String jdbcClass) {
    this.jdbcClass = jdbcClass;
  }
  public String getJdbcClass() {
    return jdbcClass;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getUserName() {
    return userName;
  }
  public void setPasswd(String passwd) {
    this.passwd = passwd;
  }
  public String getPasswd() {
    return passwd;
  }

  public int doAfterBody() throws JspTagException {
    BodyContent bc = getBodyContent();
    String query = bc.getString();
    bc.clearBody();
    try {
      // ドライバクラスをロード
      Class.forName(jdbcClass);
      // データベースへ接続
      con = DriverManager.getConnection(url, userName, passwd);
      // ステートメントオブジェクトを生成
      stmt = con.createStatement();
      // 結果セットを取得
      ResultSet result = stmt.executeQuery(query);
      // 属性をセット
      pageContext.setAttribute(id,result);
    } catch (Exception e) {
      throw new JspTagException(e.getMessage());
    }
    return SKIP_BODY;
  }
  public void release() {
    try {
      stmt.close();
      con.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
 
■検索結果を表示するタグハンドラ(タグ名:foreach)
HelloWorldBodyTag.java(ここからダウンロード)
package javahello;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;
import java.io.*;

public class HelloWorldBodyTag extends BodyTagSupport {
  private ResultSet result;

  public HelloWorldBodyTag() {
    super();
  }
  public ResultSet getResult() {
    return result;
  }
  public void setResult(ResultSet result) {
    this.result = result;
  }

  public int doStartTag() throws JspTagException {
    result = (ResultSet) pageContext.getAttribute(id);
    try {
      if (result.next()) {
        pageContext.setAttribute(id, result);
        // 結果が存在する場合はボディを評価する
        return EVAL_BODY_AGAIN;
      } else {
        return SKIP_BODY;
      }
    } catch (Exception e) {
      throw new JspTagException(e.getMessage());
    }
  }

  public int doAfterBody() throws JspTagException {
    // ボディの内容を取得
    BodyContent body = getBodyContent();
    try {
      // ボディを出力
      body.writeOut(getPreviousOut());
    } catch (IOException e) {
      throw new JspTagException(e.getMessage());
    }
    body.clearBody();
    try {
      if (result.next()) {
        // まだ行が残っている場合はボディの評価を繰り返す
        return EVAL_BODY_AGAIN;
      } else {
        return SKIP_BODY;
      }
    } catch (SQLException e) {
      throw new JspTagException(e.getMessage());
    }
  }

  public int doEndTag() {
    return EVAL_PAGE;
  }

  public void release() {
    result = null;
  }
}
 
■メソッドの説明
メソッド 説明
doStartTag() 開始タグを処理するメソッド
doAfterBody() ボディ評価後の処理をするメソッド
doEndTag() 終了タグを処理するメソッド
release() リソースの開放を行うメソッド
■メソッドの戻り値の説明
メソッド 戻り値 説明
doStartTag() SKIP_BODY ボディをJSPとして評価しない場合
EVAL_BODY_AGAIN ボディをJSPとして評価する場合
doAfterBody() SKIP_BODY ボディをJSPとして評価しない場合
EVAL_BODY_AGAIN 再びボディをJSPとして評価する場合
doEndTag() SKIP_PAGE
終了タグ以降のJSPを評価しない
EVAL_PAGE
終了タグ以降のJSPを評価する
◆TEIクラスの作成
TEI(Tag extra infomation)クラスを使用すればタグの中の属性に設定されている値を変数として使用することができます。この変数のことをスクリプト変数といいます。TEIクラスはTagExtraInfoクラスを継承します。
例)
<hw:foreach id="helloResult">
<%=helloResult.getInt("NO") %>
</hw:foreach>
◆TEIクラスのコード
HelloWorldBodyTEI.java(ここからダウンロード)
package javahello;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.IOException;

public class HelloWorldBodyTEI extends TagExtraInfo {
  public VariableInfo[] getVariableInfo(TagData tagData) {
    VariableInfo[] vars = new VariableInfo[1];
    vars[0] = new VariableInfo(tagData.getId(), 
                               "java.sql.ResultSet", 
                               true,
                               VariableInfo.NESTED);
    return vars;
  }
}
 
■説明
getVariableInfoメソッドで使用するスクリプト変数の情報を返すようにします。戻り値はVariableInfoクラスの使用するスクリプト変数の数の長さの配列になります。VariableInfoクラスについてはJ2EEのJava APIドキュメントを参照してください。
◆タグディスクリプタライブラリファイルの編集
タグディスクリプタライブラリファイルを以下のように編集します。
helloworld.tld(ここからダウンロード)
<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE taglib PUBLIC 
   "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" 
   "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
  <tlibversion>1.0</tlibversion>
  <jspversion>1.1</jspversion>
  <shortname>javahello</shortname>
  <info>JavaでHello World タグライブラリ</info>

  <tag>
    <name>helloworld</name>
    <tagclass>javahello.HelloWorldTag</tagclass>
    <bodycontent>empty</bodycontent>
    <info>Hello Worldと出力</info>
  </tag>

  <tag>
    <name>query</name>
    <tagclass>javahello.HelloWorldQueryTag</tagclass>
    <bodycontent>tagdependent</bodycontent>
    <info>結果セットを取得</info>

    <attribute>
      <name>url</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>jdbcClass</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>userName</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>passwd</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>id</name>
      <required>true</required>
    </attribute>
  </tag>

  <tag>
    <name>foreach</name>
    <tagclass>javahello.HelloWorldBodyTag</tagclass>
    <teiclass>javahello.HelloWorldBodyTEI</teiclass>
    <bodycontent>JSP</bodycontent>
    <info>結果セットを表示</info>

    <attribute>
      <name>id</name>
      <required>true</required>
    </attribute>
  </tag>
</taglib>
 
◆JSPコード
helloworldbodytag.jsp(ここからダウンロード)

<%@ page contentType="text/html; charset=Shift_JIS" %>
<%@ page import="javahello.*" %>
<%@ taglib uri="/jsp/helloworld.tld" prefix="hw" %>
<html>
<head>
<title>Hello World Jsp Custom Tag</title>
</head>
<body>
<hw:query jdbcClass="org.gjt.mm.mysql.Driver"
        url="jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS"
        userName=""
        passwd=""
        id="helloResult">
SELECT * FROM HELLO_WORLD_TABLE
</hw:query>

<table border="1">
<tr>
<th>NO</th>
<th>言語</th>
<th>メッセージ</th>
</tr>
<hw:foreach id="helloResult">
<tr>
<td><%=helloResult.getInt("NO") %></td>
<td><%=helloResult.getString("LANGUAGE") %></td>
<td><%=helloResult.getString("MESSAGE") %></td>
</tr>
</hw:foreach>
</table>
</body>
</html>

 
 
◆TomcatへのファイルのコピーとTomcatの再起動
Tomcatで見れるようにするためにファイルをコピーします。

HelloWorldQueryTag.class → Tomcatのフォルダ\webapps\examples\WEB-INF\classes\javahello
HelloWorldBodyTag.class → Tomcatのフォルダ\webapps\examples\WEB-INF\classes\javahello
HelloWorldBodyTEI.class → Tomcatのフォルダ\webapps\examples\WEB-INF\classes\javahello
helloworld.tld → Tomcatのフォルダ\webapps\examples\jsp
helloworldbodytag.jsp → Tomcatのフォルダ\webapps\examples\jsp
◆データベースの用意
データベースの作成、テーブル作成、データ登録はJDBC(MySQL)編と全く同じ設定にしてください。
◆MySQLのドライバをTomcatで使用可能にする
mysql-connector-java-○.○-bin.jarファイルを[Tomcatのフォルダ]\shared\lib または、[WEBアプリケーションのフォルダ]\WEB-INF\libの下にコピーしてください。コピーしたらTomcatを再起動してください。 コピーしましたらTomcatを再起動してください。
◆ブラウザで見てみよう!
http://localhost:8080/examples/jsp/helloworldbodytag.jsp
おおおおお!表示されましたね!
 
■書籍
Java関連の書籍
■ツール
ツールの部屋

 
  ネットで買えば断然お得!お買い物なら楽天市場
ツールの部屋 - Java関連の書籍 - デザインパターン - 情報交換掲示板 - HOME