WebLogic Web サービス プログラマーズ ガイド
![]() |
![]() |
![]() |
![]() |
この章では、単純な WebLogic Web サービスを作成する方法について説明します。
この例では、WL_HOME
/samples/server/examples/src/examples/webservices/complex/statelessSession
ディレクトリに製品例として格納されている WebLogic Web サービスの実装、アセンブル、およびデプロイのプロセスを始めから終わりまで説明します。WL_HOME
は WebLogic Platform のメイン ディレクトリ (d:\beahome\weblogic81
など) です。
この例では、WebLogic Web サービスをステートレス セッション EJB に基づいて作成する方法を示します。この例では、Trader
EJB (WL_HOME
/samples/server/examples/src/examples/ejb20/basic/statelessSession
ディレクトリにある EJB 2.0 対応サンプルの 1 つ) を使用しています。
Trader
EJB では、入力として株式シンボルである String
と購入または売却する株数である int
を受け取る、buy()
と sell()
という 2 つのメソッドが定義されています。これらのメソッドはともに、TraderResult
という非組み込みデータ型を返します。
Trader
EJB が Web サービスに変換されると、この 2 つのメソッドは、この Web サービスの WSDL で定義されるパブリック オペレーションとなります。Client.java
アプリケーションは、JAX-RPC クライアント API を使用してオペレーションを呼び出す SOAP メッセージを作成します。
下記の手順は、サンプル WL_HOME
/samples/server/examples/src/examples/webservices/complex/statelessSession
を構築して実行する方法を示しています。サンプル ディレクトリの build.xml
Ant ビルド ファイルを使用して、EJB Java ソース コードをクラス ファイルにコンパイルしたり、servicegen
WebLogic Web サービスの Ant タスクを実行したり、Web サービスを WebLogic Server にデプロイしたりといった主な手順をすべて実行します。「例の構造」では、例を構成する主要な構成要素 (ステートレス セッション EJB や非組み込みデータ型など) について説明します。
注意 :この節の説明は、WebLogic Server と一緒にデフォルトでインストールされる例としての WebLogic Server ドメインが開始されていることを前提としています。サンプル サーバのドメイン ディレクトリは、WL_HOME
\samples\domains\examples
です。
サンプルの Trader
WebLogic Web サービスを構築して実行するには、次の手順を行います。
Windows NT では、setExamplesEnv.cmd
コマンドを実行します。このコマンドは、WL_HOME
\samples\domains\examples
ディレクトリにあります。WL_HOME
は WebLogic Platform のメイン ディレクトリです (d:\beahome\weblogic81
など)。
UNIX では、setEnv.sh
コマンドを実行します。このコマンドは、WL_HOME
/samples/domains/examples
ディレクトリにあります。WL_HOME
は WebLogic Platform のメイン ディレクトリです (/beahome/weblogic81
など)。
prompt> ant
*.java
ファイルから EJB JAR ファイルを作成するTradeResult
非組み込みデータ型のシリアライゼーション クラスを自動的に生成する servicegen
Ant タスクを実行し、web-services.xml
ファイルを作成して、それらすべての要素をデプロイ可能な EAR ファイルにパッケージ化する clientgen
Ant タスクを実行して、Web サービスを呼び出すために必要なすべてのクラスとインタフェースが格納されたローカル クライアントの JAR ファイルを作成するClient.java
クライアント アプリケーションをコンパイルする
prompt> ant run
例が正常に実行されると、クライアント アプリケーションを実行したウィンドウと WebLogic Server のコンソール ウィンドウの両方で次の出力が表示されるはずです。
[java] Buying 100 shares of BEAS.
[java] Result traded 100 shares of BEAS
[java] Buying 200 shares of MSFT.
[java] Result traded 200 shares of MSFT
[java] Buying 300 shares of AMZN.
[java] Result traded 300 shares of AMZN
[java] Buying 400 shares of HWP.
[java] Result traded 400 shares of HWP
[java] Selling 100 shares of BEAS.
[java] Result traded 100 shares of BEAS
[java] Selling 200 shares of MSFT.
[java] Result traded 200 shares of MSFT
[java] Selling 300 shares of AMZN.
[java] Result traded 300 shares of AMZN
[java] Selling 400 shares of HWP.
[java] Result traded 400 shares of HWP
http://localhost:port/webservice/TraderService
この節では、「Trader WebLogic Web サービス (例) の構築と実行」で構築して実行した例を構成する以下の主要な要素について説明します。
Web サービスの例は、ステートレス セッション EJB に基づいています。Trader
EJB では、入力として株式シンボルである String
と購入または売却する株数である int
を受け取る、buy()
と sell()
という 2 つのメソッドが定義されています。 これらのメソッドはともに、TraderResult
という非組み込みデータ型を返します。
以下の Java インタフェースと実装クラスで、Trader
EJB が定義されています。
package examples.webservices.complex.statelessSession;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
/**
* このインタフェース内のメソッドは TraderBean のパブリック インタフェース
* これらのメソッドのシグネチャは EJBean のシグネチャと同じだが、
* java.rmi.RemoteException を送出する点で異なる
* EJBean はこのインタフェースを実装していないことに注意すること。対応する
* コード生成の EJBObject である TraderBean は、このインタフェースを実装し
* Bean に委託する
*
* @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
*/
public interface Trader extends EJBObject {
/**
* 株式を購入する
*
* @param stockSymbol String 株式シンボル
* @param shares int 購入する株数
* @return TradeResult 取引結果
* @exception 通信またはシステムに障害がある場合は
* RemoteException を送出
*/
public TradeResult buy (String stockSymbol, int shares)
throws RemoteException;
/**
* 株式を売却する
*
* @param stockSymbol String 株式シンボル
* @param shares int 売却する株数
* @return TradeResult 取引結果
* @exception 通信またはシステムに障害がある場合は
* RemoteException を送出
*/
public TradeResult sell (String stockSymbol, int shares)
throws RemoteException;
}
package examples.webservices.complex.statelessSession;
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* TraderBean は、ステートレス セッション Bean。 この Bean は以下を表す
* <ul>
* <li> セッション Bean への呼び出しと呼び出しの間に永続性はない
* <li> 環境から値をルックアップ
* </ul>
*
* @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
*/
public class TraderBean implements SessionBean {
private static final boolean VERBOSE = true;
private SessionContext ctx;
private int tradeLimit;
// WebLogic のログ サービスの使用も検討すること
private void log(String s) {
if (VERBOSE) System.out.println(s);
}
/**
* このメソッドは EJB 仕様では必須だが、
* このサンプルでは使用されない
*
*/
public void ejbActivate() {
log("ejbActivate called");
}
/**
* このメソッドは EJB 仕様では必須だが、
* このサンプルでは使用されない
*
*/
public void ejbRemove() {
log("ejbRemove called");
}
/**
* このメソッドは EJB 仕様では必須だが、
* このサンプルでは使用されない
*
*/
public void ejbPassivate() {
log("ejbPassivate called");
}
/**
* セッション コンテキストを設定
*
* @param ctx SessionContext セッションのコンテキスト
*/
public void setSessionContext(SessionContext ctx) {
log("setSessionContext called");
this.ctx = ctx;
}
/**
* このメソッドは、ホーム インタフェース「TraderHome.java」の create
* メソッドに対応する
* 2 つのメソッドのパラメータ セットは同じ。 クライアントが
* <code>TraderHome.create()</code> を呼び出すと、コンテナは EJBean
* のインスタンスを割り当てて、<code>ejbCreate()</code> を呼び出す
*
* @exception 通信またはシステムに障害がある場合は
* javax.ejb.CreateException を送出
* @see examples.ejb11.basic.statelessSession.Trader
*/
public void ejbCreate () throws CreateException {
log("ejbCreate called");
try {
InitialContext ic = new InitialContext();
Integer tl = (Integer) ic.lookup("java:/comp/env/tradeLimit");
tradeLimit = tl.intValue();
} catch (NamingException ne) {
throw new CreateException("Failed to find environment value "+ne);
}
}
/**
* 指名された顧客に代わって株式を購入
*
* @param customerName String 顧客の名前
* @param stockSymbol String 株式シンボル
* @param shares int 購入する株数
* @return TradeResult 取引結果
* 株式の購入中にエラーがある場合
*/
public TradeResult buy(String stockSymbol, int shares) {
if (shares > tradeLimit) {
log("Attempt to buy "+shares+" is greater than limit of "+tradeLimit);
shares = tradeLimit;
}
log("Buying "+shares+" shares of "+stockSymbol);
return new TradeResult(shares, stockSymbol);
}
/**
* 指名された顧客に代わって株式を売却
*
* @param customerName String 顧客の名前
* @param stockSymbol String 株式シンボル
* @param shares int 購入する株数
* @return TradeResult 取引結果
* 株式の売却中にエラーがある場合
*/
public TradeResult sell(String stockSymbol, int shares) {
if (shares > tradeLimit) {
log("Attempt to sell "+shares+" is greater than limit of "+tradeLimit);
shares = tradeLimit;
}
log("Selling "+shares+" shares of "+stockSymbol);
return new TradeResult(shares, stockSymbol);
}
}
package examples.webservices.complex.statelessSession;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
/**
* このインタフェースは、TraderBean.java のホーム インタフェース
* WebLogic では、コード生成のコンテナ クラスである TraderBeanC
* によって実装される。ホーム インタフェースは、EJBean で「ejbCreate」
* というメソッドに必ず対応する 1 つまたは複数の create メソッドをサポートできる
*
* @author Copyright (c) 1998-2003 by BEA Systems, Inc. All Rights Reserved.
*/
public interface TraderHome extends EJBHome {
/**
* このメソッドは、「WeatherBean.java」の ejbCreate
* メソッドに対応する
* 2 つのメソッドのパラメータ セットは同じ。クライアントが
* <code>TraderHome.create()</code> を呼び出すと、コンテナは EJBean
* のインスタンスを割り当てて、<code>ejbCreate()</code> を呼び出す
*
* @return Trader
* @exception 通信またはシステムに障害がある場合は
* RemoteException を送出
* @exception Bean の作成時に問題が生じた場合は
* CreateException を送出
* @see examples.ejb11.basic.statelessSession.TraderBean
*/
Trader create() throws CreateException, RemoteException;
}
EJB の 2 つのメソッドは、TraderResult
という非組み込みデータ型を返します。 次の Java コードは、このデータ型を記述しています。
package examples.webservices.complex.statelessSession;
import java.io.Serializable;
/**
* このクラスは、売買結果を反映する
*
* @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
*/
public final class TradeResult implements Serializable {
// 実際に売買された株数
private int numberTraded;
private String stockSymbol;
public TradeResult() {}
public TradeResult(int nt, String ss) {
numberTraded = nt;
stockSymbol = ss;
}
public int getNumberTraded() { return numberTraded; }
public void setNumberTraded(int numberTraded) {
this.numberTraded = numberTraded;
}
public String getStockSymbol() { return stockSymbol; }
public void setStockSymbol(String stockSymbol) {
this.stockSymbol = stockSymbol;
}
}
Trader
EJB では、それ自体を記述する以下の 2 つのデプロイメント記述子ファイルを定義します。
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>TraderService</ejb-name>
<home>examples.webservices.complex.statelessSession.TraderHome</home>
<remote>examples.webservices.complex.statelessSession.Trader</remote>
<ejb-class>examples.webservices.complex.statelessSession.TraderBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<env-entry>
<env-entry-name>WEBL</env-entry-name>
<env-entry-type>java.lang.Double </env-entry-type>
<env-entry-value>10.0</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>INTL</env-entry-name>
<env-entry-type>java.lang.Double </env-entry-type>
<env-entry-value>15.0</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>tradeLimit</env-entry-name>
<env-entry-type>java.lang.Integer </env-entry-type>
<env-entry-value>500</env-entry-value>
</env-entry>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>TraderService</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 7.0.0 EJB//EN'
'http://www.bea.com/servers/wls700/dtd/weblogic700-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>TraderService</ejb-name>
<jndi-name>webservices-complex-statelessession</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
Ant ビルド ファイル build.xml
には、trader.jar
EJB ファイルを参照する servicegen
Ant タスクへの呼び出しが含まれています。また Ant ビルド ファイルは、次の作業も行います。
web-services.xml
デプロイメント記述子ファイルを作成するtrader.ear
ファイルにパッケージ化するサンプル build.xml
ファイルからの次の抜粋には、EAR ファイルを一時的な build_dir
ディレクトリに作成する指示が記述されています。
<target name="build" >
<delete dir="build_dir" />
<mkdir dir="build_dir" />
<copy todir="build_dir" file="trader.jar"/>
<servicegen
destEar="build_dir/trader.ear"
warName="trader.war"
contextURI="webservice">
<service
ejbJar="build_dir/trader.jar"
targetNamespace="http://www.bea.com/examples/Trader"
serviceName="TraderService"
serviceURI="/TraderService"
generateTypes="True"
expandMethods="True" >
</service>
</servicegen>
</target>
次の Java クライアント アプリケーションは、JAX-RPC API を使用して、デプロイされた Trader
Web サービスの購入および売却オペレーションを呼び出す方法を示しています。
package examples.webservices.complex.statelessSession;
/**
* このクラスは JAX-RPC API を使用して TraderService を呼び出す方法を示す
* 以下のタスクを実行する Web サービス
* <ul>
* <li> 100 株購入する
* <li> 100 株売却する
* </ul>
*
* TraderService Web サービスは、Trader ステートレス セッション EJB を使用して
* 実装される
* * @author Copyright (c) 1998-2003 by BEA Systems, Inc. All Rights Reserved.
*/
public class Client {
public static void main(String[] args) throws Exception {
// グローバルな JAXM メッセージ ファクトリをセットアップする
System.setProperty("javax.xml.soap.MessageFactory",
"weblogic.webservice.core.soap.MessageFactoryImpl");
// グローバルな JAX-RPC サービス ファクトリをセットアップする
System.setProperty( "javax.xml.rpc.ServiceFactory",
"weblogic.webservice.core.rpc.ServiceFactoryImpl");
// 引数リストの解析
Client client = new Client();
String wsdl = (args.length > 0? args[0] : null);
client.example(wsdl);
}
public void example(String wsdlURI) throws Exception {
TraderServicePort trader = null;
if (wsdlURI == null) {
trader = new TraderService_Impl().getTraderServicePort();
} else {
trader = new TraderService_Impl(wsdlURI).getTraderServicePort();
}
String [] stocks = {"BEAS", "MSFT", "AMZN", "HWP" };
// 購入を実行する
for (int i=0; i<stocks.length; i++) {
int shares = (i+1) * 100;
log("Buying "+shares+" shares of "+stocks[i]+".");
TradeResult result = trader.buy(stocks[i], shares);
log("Result traded "+result.getNumberTraded()
+" shares of "+result.getStockSymbol());
}
// 売却を実行する
for (int i=0; i<stocks.length; i++) {
int shares = (i+1) * 100;
log("Selling "+shares+" shares of "+stocks[i]+".");
TradeResult result = trader.sell(stocks[i], shares);
log("Result traded "+result.getNumberTraded()
+" shares of "+result.getStockSymbol());
}
}
private static void log(String s) {
System.out.println(s);
}
}
![]() ![]() |
![]() |
![]() |