リクエスト情報を制御するアクションフォームBeansStrutsを使うWebアプリケーション構築術(4)(2/3 ページ)

» 2004年05月01日 00時00分 公開
[山田祥寛@IT]

DynaActionFormでリクエストデータの授受を簡略化

 第2回「Strutsフレームワークの『枠組み』を学ぶ」で紹介したアクションフォームBeansクラスBeginFormを読まれた方は、「アクションフォームBeansは、単なるプライベート変数とアクセサメソッドの集合ではないのか」と思われたかもしれません。確かに、ただ単にデータの授受だけに限定すれば、アクションフォームBeansは「単なるプライベート変数とアクセサメソッドとの集合」にすぎません。そして、リクエストパラメータさえ決まれば、自動的に生成できてしまうたぐいのものです。「このようなものに」人間の手をいちいち煩わせなければならないのはナンセンスですし、人間の手を介することでかえって間違いや不整合を引き起こすもとにもなります。

 そこで、Struts1.1から導入されたのが、DynaActionFormの概念です。DynaActionFormを利用することで、コンフィグレーションファイルに一連のリクエストパラメータ名とデータ型を定義するだけで、リクエストパラメータの定義をいちいちアクションフォームBeansクラスとして記述する必要がなくなります。

 以下では、前回ご紹介したグリッド表内から個別詳細画面にリンクする際に引き渡されるリクエストパラメータ(クエリ情報"isbn")をDynaActionFormで定義してみることにしましょう。

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>
  …中略…
  <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-beans>
  …中略…
</struts-config>

 実に単純だとは思いませんか。DynaActionFormを使用する場合の一般的な構文は、以下のとおりです。

<form-bean name="アクションフォームBeans名"
  type="org.apache.struts.action.DynaActionForm">
  <form-property name="パラメータ名" type="データ型"
    [initials="初期値"] [size="要素数"] />
  <!--<form-property>要素の繰り返し-->
</form-bean>

 DynaActionFormを使用する場合には、<form-bean>要素のtype属性には、固定値として“org.apache.struts.action.DynaActionForm”を指定しています。

 <form-property>要素には、DynaActionFormを介して受け渡ししたいリクエストパラメータの値を指定します。<form-bean>要素配下に、パラメータ数に応じて、複数個列記することができます。name属性とtype属性は必須で、type属性に指定可能なデータ型には、各データ型に関する配列(例:String[])、Mapインターフェイスの実装クラス(例:HashMap)、Listインターフェイスの実装クラス(例:ArrayList)などのほか、下表のようなものがあります。

type属性(<form-property>要素)で指定可能なデータ型
java.lang.BigDecimal java.lang.BigInteger boolean(java.lang.Boolean)
byte(java.lang.Byte) char(java.lang.Character) java.lang.Class
double(java.lang.Double) float(java.lang.Float) int(java.lang.Integer)
long(java.lang.Long) short(java.lang.Short) java.lang.String
java.sql.Date java.sql.Time java.sql.Timestamp

 また、今回は省略していますが、パラメータに初期値を与えたいという場合には、次のようにinitial属性で指定することも可能です。

<form-property name="isb" type="java.lang.String" initial="X-XXXXX-XX" />
<form-property name="author" type="java.lang.String[]"
  initial="'Y.Yamada','E.Moriyama','Y.Fuchi'" />

 配列値を指定する場合は、各要素を「'」で囲み、要素間を「,」で区切ります。initial属性が省略された場合にはnull(数値の場合は0)が初期値として与えられます。また、配列型に対してサイズだけを指定しておきたい場合には、size属性を使用します。

<form-property name="author" type="java.lang.String[]" size="3" />

DynaActionFormからリクエストデータを取得する

 次に、コンフィグレーションファイルで指定したDynaActionFormの内容を、アクションクラスから引用してみることにしましょう。まずは、具体的なコードを概観してください。

 下記のコードは、新規登録・更新・削除の処理を行います。

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

import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.*;
import org.apache.struts.action.*;
import org.apache.commons.beanutils.*;

public final class BookUpdateViewProcess extends Action {
  public ActionForward execute (ActionMapping map, 
    ActionForm fm, HttpServletRequest request, 
    HttpServletResponse response) {
    DynaBean objFrm=(DynaBean)fm;
    BookInfo objBok=null;
     /* リンク元(第3回で紹介したBookView.jsp)からクエリ情報“isbn”が
      * 渡されたかどうか。渡された場合のみ、データベースから該当する
      * 書籍情報を取得し、BookInfoクラスにセットします */
    if(objFrm.get("isbn")!=null && !objFrm.get("isbn").equals("")){
      objBok=BookInfo.getBookInfo((String)objFrm.get("isbn"));
         /* 書籍情報リストからクエリ情報が渡されたことを示すフラグ
          * として、リクエスト属性“update.flag”に“true”をセット。
          * “update.flag”は、後述するBookUpdate.jspで使用します */
      request.setAttribute("update.flag","true");
    }
     /* リクエスト属性“book.update.info”にBookInfoクラスをセット。
      * BookView.jspから[新規登録]がクリックされた場合には、空の
      * BookInfoクラスがセットされます */
    request.setAttribute("book.update.info",objBok);
    return map.findForward("success");
  }
}

 書籍情報一覧のコードは、前回作成したものに対して以下のように追記を行っています。

BookInfo.java
(前回からの追記分のみ。コンパイル結果は「/WEB-INF/classes/struts」に保存)
package struts;

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

public final class BookInfo implements Serializable {
  …中略…
  // 与えられたISBN番号(id)に合致する書籍情報をBookInfoオブジェクト
  // として返します。
  public static BookInfo getBookInfo(String id) {
    Connection db=null;
    PreparedStatement objPs=null;
    ResultSet rs=null;
    BookInfo objBok=new BookInfo();
    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 WHERE isbn=?");
      objPs.setString(1,id);
      rs=objPs.executeQuery();
       // 取得した書籍情報をBookInfoオブジェクトにセット
      if(rs.next()){
        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"));
      }
    } 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 objBok;
  }
  …中略…
}

 大まかなロジックの流れはコード中のコメントを参照していただくとして、ここではDynaActionFormの内容を取得する部分に注目してみることにしましょう。

 DynaActionFormの具体的なインスタンス(オブジェクト)を取得するには、executeメソッドの引数として渡されたActionFormクラスfmを、まずDynaBeanクラスにキャスティングしておく必要があります。

DynaBean objFrm=(DynaBean)fm;

 これを行っておかないと、コンフィグレーションファイルで設定した個別のプロパティにアクセスすることができないので注意が必要です。DynaBeanは、org.apache.commons.beanutilsパッケージであらかじめ用意されたプロパティを動的に取得するための汎用クラスです。

 キャスティングによってDynaBeanオブジェクトを取得したら、後はgetメソッドで個別のプロパティにアクセスすることができます。ただし、getメソッドの戻り値型はObjectクラスです。使用する際は、必ず事前に適切な型にキャスティングしておくのを忘れないようにしてください。

(String)(objFrm.get("isbn"))

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

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

メールマガジン登録

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