連載
» 2004年03月06日 00時00分 公開

Strutsとデータベースの連携を学ぶStrutsを使うWebアプリケーション構築術(3)(2/2 ページ)

[山田祥寛,@IT]
前のページへ 1|2       

データベースからの抽出結果をJavaBeansクラスにセットする

 データベースへの接続・操作を担当するのは、JavaBeansクラスBookInfoの役割です。BookInfoクラスのgetBookInfosメソッドでは、書籍情報テーブル(bok_inf_tbl)の内容を配本日(publishedフィールド)降順で抽出し、取得した結果セットを後続のビュー(BookView.jsp)に引き渡します。

 ただし、取得した結果セットをそのまま「.jsp」ファイルに引き継いでも、「.jsp」ファイルではこれを扱うことができません(もちろん、スクリプトレットなどを利用すれば可能です)。後続の「.jsp」ファイル内において、「Strutsタグライブラリ」だけで結果セットの内容を処理するには、結果セットからJavaBeansクラスの配列を作成しておく必要があるのです。Strutsでは標準的に結果セット(ResultSetオブジェクト)を処理するための機能(タグライブラリ)は用意していませんが、データをJavaBeans配列の形式に加工しておくことでデータを容易に処理することができるようになります(処理方法については後述)。

 BookInfoクラスでは、bok_inf_tblテーブルから抽出した結果セットの1行を1つのオブジェクトで表現します。getBookInfosメソッドでは、データソースから抽出した結果セットの内容を1行ずつ取り出し、BookInfoクラスの各プロパティ(フィールド)に格納していきます。出来上がったBookInfoクラスは、ArrayList(可変配列)に順に追加していくことで、最終的にループ処理がすべて完了したときには、BookInfoクラスの配列ができているというわけです。

 なお、ここではデータベース操作の基本的な手法については割愛しますので、詳細は「基礎から学ぶサーブレット/JSP 第10回」「JNDI活用でデータソース管理を一元化する」を参考にしてください。

BookInfo.java(コンパイル結果は「/WEB-INF/classes/struts」に保存)
package struts;

import java.io.*;
import java.sql.*;
import java.util.*;
import javax.sql.*;
import javax.naming.*;

public final class BookInfo implements Serializable {
   // 各レコードのフィールド値を格納するためのプライベート変数
  private String isbn;
  private String title;
  private String author;
  private String price;
  private String publish;
  private String published;
   // コンストラクタ
  public BookInfo() {
    isbn=null;   title=null;
    author=null; price=null;
    publish=null;published=null;
  }
   // プロパティ参照用のgetterメソッド
  public String getIsbn()     {return isbn;}
  public String getTitle()    {return title;}
  public String getAuthor()   {return author;}
  public String getPrice()    {return price;}
  public String getPublish()  {return publish;}
  public String getPublished(){return published;}
   // プロパティ設定用のsetterメソッド
  public void setIsbn(String isbn)        {this.isbn=isbn;}
  public void setTitle(String title)      {this.title=title;}
  public void setAuthor(String author)    {this.author=author;}
  public void setPrice(String price)      {this.price=price;}
  public void setPublish(String publish)  {this.publish=publish;}
  public void setPublished(String published){this.published=published;}
   // データベースからの出力結果をArrayListオブジェクトに格納
  public static ArrayList getBookInfos() {
    ArrayList objAry=new ArrayList();
    Connection db=null;
    PreparedStatement objPs=null;
    ResultSet rs=null;
    try {
       // データベースへの接続を確立
      Context ctx=new InitialContext();
      DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/Struts");
      db=ds.getConnection();
      objPs=db.prepareStatement("SELECT * FROM bok_inf_tbl ORDER BY published DESC");
      rs=objPs.executeQuery();
       // 取得した結果セットをもとに、BookInfo配列を生成
      while(rs.next()){
        BookInfo objBok=new BookInfo();
        objBok.setIsbn(rs.getString("isbn"));
        objBok.setTitle(rs.getString("title"));
        objBok.setAuthor(rs.getString("author"));
        objBok.setPrice(rs.getString("price"));
        objBok.setPublish(rs.getString("publish"));
        objBok.setPublished(rs.getString("published"));
        objAry.add(objBok);
      }
    } catch(Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if(rs!=null)   {rs.close();}
        if(objPs!=null){objPs.close();}
        if(db!=null)   {db.close();}
      } catch(Exception e){
        e.printStackTrace();
      }
    }
    return objAry;
  }
}

 完成したArrayListオブジェクトは、HttpServletRequest#setAttributeメソッドを介してリクエスト属性“book.view.info”として格納します。

JavaBeansクラスの内容を「.jsp」ファイルで出力する

 これで、データを表示するための準備ができましたので、いよいよビュー(「.jsp」ファイル)の構築です。上で用意されたBookInfoクラスの配列を、「.jsp」ファイル上でグリッド表に展開してみましょう。

BookView.jsp(「/chap03」に保存)
<%@ page contentType="text/html;charset=Shift_JIS" %>
<%@ taglib uri="/tags/struts-html"  prefix="html" %>
<%@ taglib uri="/tags/struts-bean"  prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<html:html>
<head>
<title>書籍情報更新・削除</title>
</head>
<body>
<h1 style="color:white;background-color:#525D76;">書籍情報更新・削除</h1>
[<html:link action="/BookWriteViewAction">新規登録</html:link>]
<table border="1">
  <tr bgcolor="#eeeeee">
    <th>タイトル</th><th>著者名</th><th>価格</th><th>出版社</th><th>配本日</th>
  </tr>
  <logic:iterate id="bookInfo" name="book.view.info" scope="request">
    <tr>
      <td nowrap>
        <html:link action="/BookWriteViewAction"
          paramId="isbn" paramName="bookInfo" paramProperty="isbn">
          <bean:write name="bookInfo" property="title" />
        </html:link>
      </td>
      <td nowrap><bean:write name="bookInfo" property="author" /></td>
      <td nowrap><bean:write name="bookInfo" property="price" /></td>
      <td nowrap><bean:write name="bookInfo" property="publish" /></td>
      <td nowrap><bean:write name="bookInfo" property="published" /></td>
    </tr>
  </logic:iterate>
</table>
</body>
</html:html>

 配列から順番に要素を取り出し、出力するのは、<logic:iterate>要素の役割です。name属性で指定された「属性」値を、scope属性で指定されたスコープから検出します。id属性は、<logic:iterate>要素の配下で、取り出された要素(個々のJavaBeansクラス)にアクセスする場合の変数名となります。

 <logic:iterate>要素配下では、<bean:write>要素を使用することで、JavaBeansクラスの個々のプロパティにアクセスすることができます。<bean:write>要素のname属性は、<logic:iterate>要素のid属性に対応している必要があります。property属性には、取得したいプロパティ名を、それぞれ指定してください。

 なお、タイトル列には、詳細画面(次回紹介)にジャンプするためのハイパーリンクを作成することにします。ハイパーリンクの作成には、<html:link>要素を使用します。以下に、<html:link>要素で利用可能な主な属性を挙げておくことにしましょう。

<html:link>要素の主な属性
属性 概要
action リンク先のアクション名
paramId クエリ情報のキー名
paramName クエリ情報の値(JavaBeansクラス)
paramProperty クエリ情報の値(プロパティ名)

 配下には、リンク文字列として使用される文字列を指定します。つまり、<html:link>要素によって、(例えば)以下のような<a>タグが生成されます。

<a href="/struts/BookWriteViewAction.do?isbn=4-7980-0522-3">
プチリファレンスJSP&サーブレット</a>

 <logic:iterate>要素と併用することで、一覧表に個別画面へのリンクを生成するこの手法は、比較的よく利用する定石的な方法でもありますので、きちんと押さえておいてください。

関係ファイルをマッピングする

 最後に、これまで作成したアクションクラス、アクションフォームBeans、「.jsp」ファイルを、コンフィグレーションファイル上でマッピング(関連付け)して、完了です。struts-config.xmlに、以下のリストの赤字部分を追記してください。

struts-config.xml
<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
  <data-sources>
    <data-source type="org.apache.commons.dbcp.BasicDataSource">
      <set-property property="driverClassName"
        value="org.gjt.mm.mysql.Driver" />
      <set-property property="url" value="jdbc:mysql://localhost/wings?useUnicode=
true&amp;characterEncoding=Shift_JIS" />
      <set-property property="username" value="root" />
      <set-property property="password" value="root" />
    </data-source>
  </data-sources>
  <form-beans>
    <form-bean name="BeginForm" type="struts.BeginForm" />
    <form-bean name="BookUpdateViewForm"
      type="org.apache.struts.action.DynaActionForm">
      <form-property name="isbn" type="java.lang.String" />
    </form-bean>
    <form-bean name="BookUpdateForm" type="struts.BookUpdateForm" />
  </form-beans>
  <global-exceptions>
  </global-exceptions>
  <global-forwards>
  </global-forwards>
  <action-mappings>
    <action path="/BeginAction" type="struts.BeginProcess"
      name="BeginForm" scope="request">
      <forward name="success" path="/output.jsp" />
    </action>
    <action path="/BookViewAction" type="struts.BookViewProcess">
      <forward name="success" path="/chap03/BookView.jsp" />
    </action>

    <action path="/BookWriteViewAction" type="struts.BookUpdateViewProcess"
      name="BookUpdateViewForm" scope="request">
      <forward name="success" path="/chap04/BookUpdate.jsp" />
    </action>
    <action path="/BookWriteAction" type="struts.BookUpdateProcess"
      name="BookUpdateForm" scope="request"
      input="/chap04/BookUpdate.jsp" validate="false">
      <forward name="success" path="/BookViewAction.do" />
    </action>
  </action-mappings>
  <message-resources parameter="ApplicationResources" />
  <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames" value="/WEB-INF/validator-rules.xml
                                             ,/WEB-INF/validation.xml" />
  </plug-in>
</struts-config>

 <action>要素の設定については、すでに「第2回 Strutsフレームワークの「枠組み」を学ぶ」でもご紹介したので、さらに加えるべき点はありません。復習も兼ねて、第2回の解説と照らし合わせながら、自分なりに解釈してみてください。

 なお、このようにコンフィグレーションファイルを設定した場合、アプリケーションは以下のURLで呼び出すことができます。

http://localhost:8080/struts/BookViewAction.do

 末尾の見慣れない拡張子「.do」を、あるいは不思議に思われた方がいらっしゃるかもしれません。しかし、これはれっきとしたStrutsの標準的な拡張子です。第1回で作成したweb.xmlをもう一度ご覧いただくと、アクションサーブレット(action)に対して、拡張子「.do」が関連付けされていることがお分かりになるはずです。

 つまり、Strutsでは拡張子「.do」でURLを指定することで、必ず一度アクションサーブレットを呼び出しているというわけです。アクションサーブレットは、URLからアクション名(ここでは「BookViewAction」)を取得し、これをキーとして関連するアクションフォームBeansやアクションクラスをコールします。

 第2回のサンプル(input.jsp)で、拡張子「.do」を意識する必要がなかったのは、ただ単に<html:form>要素がaction属性の指定値に対して、内部的に拡張子「.do」を付加していたからにすぎません。このように、ブラウザから直接にStrutsアプリケーションを呼び出す場合には、「.do」を明示的に指定する必要があります。

まとめ

 以上、今回はStrutsアプリケーションからデータベースにアクセスするための方法を学習しました。今回学習したのは最も基本的な内容にすぎませんが、逆にいうと、多くの状況で応用可能な「定石」でもあります。ただ記事を読み流すだけではなく、自分の手を動かしつつ、自分の目で動作を確認してみてください。きっとそこには「読む」だけでは得られなかった新たな発見があるはずです。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。