ページの先頭行へ戻る
 Apcoordinatorユーザーズガイド
FUJITSU Software

20.2.3 セションBeanとクライアントとの連携

20.2.3.1 セション情報の同期

セション同期機能によって、クライアントからセションBeanを呼び出す時に、クライアントのセションクラスが持つ情報と、セションBeanのセションクラスが持つ情報を互いに自動的に転送させることができます。

セションBeanを呼び出した時に、クライアントのセションクラスが持つ情報は、セションBeanに転送されてセションクラスにセットされます。セションBeanの呼び出しが終了するときに、セションBeanのセションクラスが持つ情報は、クライアントに転送されセションクラスにセットされます。

セション同期機能を使用するには、クライアントのセションクラスとセションBeanのセションクラスを次のように作成してください。

クライアントとセションBeanの間で転送されるデータはRMI over IIOPの規約に従っている必要があります。この規約については“EJBの引数や返却値として使用可能なオブジェクト”を参照してください。

20.2.3.2 ローカル呼び出し

Apcoordinatorで作成したセションBeanは本来EJBコンテナ上で動作しますが、クライアントと同じJVM上でEJBコンテナを使用せずに動作させることもできます。EJBコンテナを使用せずに、Apcoordinatorで作成したセションBeanをクライアントから直接呼び出す機能をローカル呼び出しと呼びます。

セションBean開発時にローカル呼び出し機能を使用すると、セションBeanをEJBコンテナに配置せずにデバッグができるため、開発の効率が上がります。

ローカル呼び出しを行うには、クライアントのプログラムを次のように作成します。

ローカル呼び出しと通常の呼び出しを簡単に切り替えられるようにするには、リモートマップに以下のように記述してください。localタグのタグ名をejbに、またはその逆に書き換えるだけで、切り替えができます。

  <local name="MyLocalSessionBean" application="java:comp/env/ejb/MySessionBean" 
                                      class="mypackage.MySessionBean">
    <env-entry>
      <env-entry-name>guestUser</env-entry-name>
      <env-entry-type>java.lang.String</env-entry-type>
      <env-entry-value>guest</env-entry-value>
    </env-entry>
  </local>

ローカル呼び出し機能を使用した場合、セションBeanに以下の制限があります。

また、以下の機能は通常の呼び出しとローカル呼び出しで動作が異なります。

20.2.3.3 データBean変換

データBean変換機能は、セションBeanを呼び出す際に、データBeanをjava.util.HashMapクラスに変換して送信する機能です。データBeanが持つ項目クラスはString, Integerなどの基本的なデータのクラスやその配列に変換されます。セションBeanがHashMapを返却した場合は、クライアントで自動的にデータBeanに変換されます。

データBeanからHashMapへの変換を正変換、HashMapからデータBeanへの変換を逆変換と呼びます。

この機能を使用すると、以下のように不要なデータを削除して通信量を減らすことができます。

データBean変換機能を使うには、EJBを呼び出すアプリケーションに“データBean変換マップ”を作成してください。データBean変換マップは、データBeanの変換規則をカスタマイズするファイルです。EJBを呼び出すアプリケーションにデータBean変換マップが存在しない場合は、データBean変換は行われません。

データBeanの変換規則

以下にデータBeanの変換例を示します。

変換前のデータBean

プロパティ名

プロパティのクラス

プロパティの値

message

String

"Hello!"

info

InfoBean
(データBean)

プロパティ名

プロパティのクラス

プロパティの値

count

int

21

date

Date

2002/4/1

choice

ComboBox
(コンボボックスの項目クラス)

選択肢番号

表示文字列

1

tokyo

東京

2

aomori

青森

3

kobe

神戸

選択されている選択肢は1

変換後のHashMap

HashMapのキー

HashMapの値のクラス

HashMapの値

message

String

"Hello!"

info

HashMap

HashMapのキー

HashMapの値のクラス

HashMapの値

count

Integer

21

date

Date

2002/4/1

choice

Integer

1

choice.value

String[]

{"tokyo","aomori","kobe"}

choice.text

String[]

{"東京","青森","神戸"}

この例で示されているように、データBeanが変換されると、各プロパティがそれぞれ変換されてHashMapに格納されます。各プロパティの変換規則は基本的に次のようになります。この変換規則はデータBean変換マップによってカスタマイズができます。

項目クラス、画面部品のインターフェイスが変換される形式の詳細は“定義ファイルリファレンス”を参照してください。

データタイプ

変換後のHashMapには、データタイプが与えられます。データタイプはHashMapに格納されたデータの種類を表す文字列です。これは、以下の目的で使用されます。

データタイプはキー"uji.type"に対応するStringの値としてHashMapに格納されます。

データBean変換マップ

データBean変換マップはデータBeanや項目クラスの変換方法を設定するファイルです。以下の設定が可能です。

データBean変換マップはXMLで次のように記述します。

<?xml version="1.0" encoding="Shift_JIS"?>
<convMap
    xmlns="http://interstage.fujitsu.com/schemas/uji/convMap"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://interstage.fujitsu.com/schemas/uji/convMap
                        http://interstage.fujitsu.com/schemas/uji/convmap.xsd">
  <config>
    <version>5.0</version>
  </config>

  <!-- mypackage.MyBeanの変換方法を指定 -->
  <class name="mypackage.MyBean">
    <beanConv target="my-bean">
      <property name="description" pass="false"/>
    </beanConv>
  </class>

  <!-- ComboBox(サブクラス含む)の選択肢はインデックス番号で送る -->
  <model name="ComboBox">
    <comboBoxConv useIndex="true"/>
  </model>
</convMap>

上記記述を例にしてデータBean変換マップの記述方法を説明します。

データBean変換マップのルートはconvMapです。 convMapの内側には、最初にconfigタグを記述し、その内側にversionタグを記述します。これはデータBean変換マップの文法のバージョンを表し、5.0を指定します。

  <config>
    <version>5.0</version>
  </config>

configタグのあとに、データBeanや項目クラスの変換方法の指定が続きます。

classタグはname属性で指定したクラスの変換方法を定義します。

  <class name="mypackage.MyBean">
    <beanConv target="my-bean">
      <property name="syokugyo" pass="false"/>
    </beanConv>
  </class>

この記述で以下を指定しています。

classタグの内側には、変換方法をあらわすタグを記述します。ここでは、beanConvタグを使用しています。このタグは、classタグで指定されたデータBeanのクラスをHashMapに変換することを意味します。HashMapのデータタイプはtarget属性で指定します。target属性が省略された場合はclassタグで指定したクラス名がデータタイプとして使用されます。

beanConvタグの内側には必要に応じてpropertyタグを記述します。このタグはname属性で指定されたプロパティを送信するかどうかをpass属性で指定します。pass="false"を指定すると送信されません。 beanConvタグとpropertyタグを使って、データBeanの特定のプロパティだけを送信するように指定するには次のように記述します。

  <class name="mypackage.MyBean">
    <beanConv target="my-bean" passByDefault="false">
      <property name="userId" pass="true"/>
    </beanConv>
  </class>

セションBeanの呼び出し時に使用したコマンド名に応じて変換方法を変更したい場合は、classタグのverb属性にコマンド名を指定して、classタグによる指定が適用されるコマンド名を限定します。

  <class name="mypackage.MyBean" verb="update">
    <beanConv target="my-bean"/>
  </class>
  <class name="mypackage.MyBean">
    <beanConv target="my-bean">
      <property name="userId" pass="false"/>
    </beanConv>
  </class>

この例では、コマンド名がupdateの場合は、すべてのプロパティが送られ、それ意外の場合はuserIdプロパティが送信されません。

以下の記述は項目クラスcom.fujitsu.uji.compo.ComboBoxの変換方法を指定します。

  <model name="ComboBox">
    <comboBoxConv useIndex="true"/>
  </model>

modelタグはname属性で指定した種類の項目クラスの変換方法を指定します。name="ComboBox"は、com.fujitsu.uji.compo.ComboBoxクラスとそのサブクラスを指定します。modelタグの内側には、変換方法をあらわすタグを記述します。ここでは、comboBoxConvタグを使用して、ComboBoxを選択肢や表示文字列の配列に変換することを指定しています。useIndex="index"は、コンボボックスの選択肢をインデックス番号で送信することを意味します。選択肢の値で送信するにはuseIndex="value"を指定します。

次のように指定すると、ComboBoxとそのサブクラスは変換されずに送信されます。

  <model name="ComboBox">
    <noConv/>
  </model>

以下の情報については“定義ファイルリファレンス”のデータBean変換マップを参照してください。

データBean変換マップのファイル名

デフォルトでは、データBean変換マップのファイル名はconv.xmlです。 Webアプリケーションでは/WEB-INFに、セションBeanでは設定ファイルフォルダに配置します。ファイル名と配置場所は初期化パラメタuji.convMapで変更できます。リモート共通インターフェイスを使用した場合は、呼び出し対象となるセションBeanごとにデータBean変換マップを指定できます。この場合、リモートマップのejbタグまたはlocalタグのconvMap属性にファイル名を指定します。

初期化パラメタuji.convMapを指定されておらず、conv.xmlが既定の配置場所に存在しない場合、データBean変換は行われません。

注意

データBean変換はクライアントで実行されるため、データBean変換マップはクライアントに作成します。セションBeanから別のセションBeanを呼び出す場合は、呼び出し側のセションBeanにデータBean変換マップを作成します。

データBeanの上書き

データBean変換機能を使用している場合、データBeanの上書き機能が利用できます。この機能は、セションBeanが返したデータをそのまま受け取るのではなく、セションBeanを呼び出したときに引数として与えたデータBeanに上書きする機能です。

以下の条件を満たす場合に上書きが可能です。

デフォルトでは上書き機能は有効に設定されています。無効に設定するには以下のようにします。

データBean変換使用時の注意事項

20.2.3.4 HashMapによるデータの入力

データBean変換機能を使ってデータBeanをHashMapに変換する場合、セションBeanは入力データとしてデータBeanではなくHashMapを受け取ります。この場合、HashMapに設定されたデータタイプに基づいて、呼び出されるビジネスクラスのメソッドが決定されます。データタイプは、HashMapのget("uji.type")で得られる文字列です。

入力データとしてHashMapを使用する場合、コマンドマップは次のように記述します。

# commands.map
$data-view;getArea=ejboffice.ejb.OfficeHandler.getArea
$data-view;search=ejboffice.ejb.OfficeHandler.search
$renew;find=ejboffice.ejb.OfficeHandler.find
$renew;update=ejboffice.ejb.OfficeHandler.update

コマンドマップの各行は次の形式で記述します。

$[データタイプ];[コマンド名]=[ビジネスクラス名].[メソッド名]

20.2.3.5 Apcoordinator以外のEJBクライアントとの連携

Apcoordinator以外のアプリケーションからApcoordinatorで作成したセションBeanを呼び出す場合のプログラミングを説明します。

セションBeanクラスは次のように作成して、execメソッドが発生するInvocationTargetExceptionにApcoordinatorの例外クラスが含まれないようにします。

以下はセションBeanクラスの記述例です。

import com.fujitsu.uji.ejb.bean.UjiSessionBean;
import java.lang.reflect.InvocationTargetException;

public class OfficeEJB extends UjiSessionBean {
        public Object[] exec(Object dataBean, String verb, Object syncData) 
            throws InvocationTargetException {
                try {
                        return super.exec(dataBean,verb,syncData);
                } catch (InvocationTargetException e) {
                        Throwable rootCause=e.getTargetException();
                        Exception replaced=new Exception(rootCause.getMessage());
                        throw new InvocationTargetException(replaced);
                }
        }
}

このように作成したセションBeanをApcoordinatorアプリケーションから呼び出す場合、セションBean内で例外が発生した際にクライアントに通知されるのはexecメソッドで作成した例外(上記の例ではExceptionクラス)になります。セションBeanのビジネスクラスで発生した例外ではありません。

クライアントのプログラムではセションBeanを以下の手順で呼び出します。

  1. JNDIを使ってホームインターフェイスを取得します。

  2. ホームインターフェイスのcreateメソッドを呼び出し、リモートインターフェイスを取得します。createメソッドの引数はありません。

  3. リモートインターフェイスのexecメソッドを呼び出します。引数には以下の3個のオブジェクトを渡します。

    • 第1引数: データBeanまたはHashMapを指定します。このオブジェクトが、セションBeanのビジネスクラスの第2引数に与えられます。

    • 第2引数: コマンドを指定します。

    • 第3引数: セションクラスに転送するオブジェクトを指定します。セションBeanがセション同期機能を使用している場合に指定してください。指定されたデータは、セションBeanにおいてsetSynchronizedDataメソッドによりセションクラスにセットされます。セション同期機能が使用されていない場合はnullを指定します。

    Apcoordinator以外のアプリケーションから呼び出す場合は、データBean変換機能は使用できません。入力データをHashMapで受け取るセションBeanに対しては、execメソッドの第1引数にHashMapを指定してください。

  4. execメソッドの返却値をの型はObject[]です。配列の各要素には以下のオブジェクトが格納されています。

    • 要素[0]: ビジネスクラスの返却値です。

    • 要素[1]: セションクラスから自動転送されたオブジェクトです。このオブジェクトは、セションBeanがセション同期機能を使用している場合に、セションクラスのgetSynchronizedDataメソッドにより取得されたものです。セション同期機能が使用されていない場合は、execメソッドの第3引数に与えたデータがそのまま返却されます。

セションBeanの実行中にアプリケーション例外が発生した場合は、execメソッドがjava.lang.reflect.InvocationTargetExceptionを発生します。

以下はセションBeanを呼び出す例です。ホームインターフェイスをSimpleBeanHome、リモートインターフェイスをSimpleBeanRemoteとしています。

import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

...

        HashMap syncData=new HashMap(); // セションBeanのセションクラスとの間で転送されるオブジェクト

        syncData.put("userId","abc1234");

...

        // ホームインターフェイス取得
        InitialContext ctx=new InitialContext();
        SimpleBeanHome home=(SimpleBeanHome)PortableRemoteObject.narrow(
                ctx.lookup("java:comp/env/ejb/SimpleBean"),SimpleBeanHome.class);
        // リモートインターフェイス取得
        SimpleBeanRemote remote=home.create();

        // セションBean呼び出し
        MessageBean bean=new MessageBean();
        bean.setMessage("Hello!");
        Object[] replyArray=remote.exec(bean,"echo",syncData);

        // 返却値の取得
        MessageBean reply=(MessageBean)replyArray[0];
        syncData=(HashMap)replyArray[1];

上記の方法でセションBeanを呼び出すEJBクライアントには、実行時ライブラリとしてujiejbcl.jarが必要です。このファイルをEJBクライアントの実行環境にコピーし、クラスパスに追加してください。 ujiejbcl.jarは、Apcoordinatorをインストールすることにより、[Apcoordinatorのインストールフォルダ]\redist\ejb にインストールされます。

ujiejbcl.jarにより、以下を利用するのに必要なクラスが提供されます。

ujiejbcl.jarは再配布可能なファイルです。クライアント環境に配布して使用できます。

20.2.3.6 EJBの引数や返却値として使用可能なオブジェクト

セションBean呼び出し時に与えるデータBeanは、以下の条件を満たす必要があります。

セションBeanが返すオブジェクトは、RMI over IIOPの規約に従っている必要があります。

RMI over IIOPでは以下の型がEJBの引数や返却値として使用できます。

例えば以下の場合は、上記の条件を満たさないため、セションBean呼び出し時にエラーが発生します。

リモート共通インターフェイスとはApcoordinatorで作成したEJBセションBeanを呼び出すためのAPIです。

上記以外の一般的なEJBの呼び出し方法は“一般的なEJBの呼び出し”を参照してください。

なお、EJBを呼び出すApcoordinatorアプリケーションを運用する際は、ご使用になるアプリケーションサーバーの説明書に従って、アプリケーションの実行環境でEJBを呼び出すのに必要な設定を行ってください。