Hitachi

Cosminexus V11 アプリケーションサーバ SOAPアプリケーション開発の手引


4.5.4 ユーザ定義のデータ型クラスを使用する場合

ユーザ定義のデータ型クラスを使用する場合のWSDLの例およびDIIのコーディング例を示します。なお,WSDLの例では次の情報が定義されています。

〈この項の構成〉

(1) WSDLの例(StockQuote.wsdl)

<wsdl:definitions 
targetNamespace="http://example.com"
xmlns:intf="http://example.com"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 
<wsdl:types>
  <schema elementFormDefault="qualified"
   targetNamespace="http://example.com"
 xmlns="http://www.w3.org/2001/XMLSchema">
 
    <element name="getLastTradePrice">
      <complexType>
        <sequence>
          <element name="in0" type="intf:TradeDate"/>
        </sequence>
      </complexType>
    </element>
 
    <complexType name="TradeDate">
      <sequence>
        <element name="date" nillable="true" type="xsd:string"/>
      </sequence>
    </complexType>
 
    <element name="getLastTradePriceResponse">
      <complexType>
        <sequence>
          <element name="getLastTradePriceReturn" type="intf:TradePrice"/>
        </sequence>
      </complexType>
    </element>
 
    <complexType name="TradePrice">
      <sequence>
        <element name="price" type="xsd:int"/>
      </sequence>
    </complexType>
 
    <element name="TradePriceException" type="intf:TradePriceException"/>
 
    <complexType name="TradePriceException">
      <sequence>
        <element name="errcode" type="xsd:int"/>
      </sequence>
    </complexType>
 
 </schema>
</wsdl:types>
 
<wsdl:message name="getLastTradePriceResponse">
  <wsdl:part name="parameters" element="intf:getLastTradePrice"/>
</wsdl:message>
 
<wsdl:message name="getLastTradePriceRequest">
  <wsdl:part name="parameters" element="intf:getLastTradePriceResponse"/>
</wsdl:message>
 
<wsdl:message name="TradePriceException">
  <wsdl:part name="fault" type="intf:TradePriceException"/>
</wsdl:message>
 
<wsdl:portType name="StockQuote">
  <wsdl:operation name="getLastTradePrice">
    <wsdl:input message="intf:getLastTradePriceRequest" name="getLastTradePriceRequest"/>
    <wsdl:output message="intf:getLastTradePriceResponse" name="getLastTradePriceResponse"/>
    <wsdl:fault message="intf:TradePriceException" name="TradePriceException"/>
  </wsdl:operation>
</wsdl:portType>
 
<wsdl:binding name="StockQuoteSoapBinding" type="intf:StockQuote">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
 
  <wsdl:operation name="getLastTradePrice">
    <soap:operation soapAction=""/>
 
    <wsdl:input name="getLastTradePriceRequest">
      <soap:body use="literal"/>
    </wsdl:input>
 
    <wsdl:output name="getLastTradePriceResponse">
      <soap:body use="literal"/>
    </wsdl:output>
 
    <wsdl:fault name="TradePriceException">
      <soap:fault name="TradePriceException" use="literal"/>
    </wsdl:fault>
  </wsdl:operation>
</wsdl:binding>
 
<wsdl:service name="StockQuoteService">
  <wsdl:port binding="intf:StockQuoteSoapBinding" name="StockQuote">
   <soap:address location="http://localhost:8080/StockQuote/services/StockQuote"/>
  </wsdl:port>
</wsdl:service>
 
</wsdl:definitions>

(2) DIIのコーディング例

// SOAPクライアントの開始
ClientID cltID = Management.initializeClient();
 
// クライアント識別子と実行スレッドを関連づける
Management.connectClientIDtoCurrentThread(cltID);
 
try {
// Serviceオブジェクトの生成
QName serviceName = new QName(
    "http://example.com",
    "StockQuoteService");
URL wsdlDocumentLocation = null;
try {
wsdlDocumentLocation = new URL("file:///C:/foo/StockQuote.wsdl");
} catch (MalformedURLException e) {
// 異常時の処理
}
 
ServiceFactory factory = null;
Service service = null;
try {
    factory = ServiceFactory.newInstance();
    service = factory.createService(wsdlDocumentLocation, serviceName);
} catch (ServiceException e) {
// 異常時の処理
}
 
// Callオブジェクトの生成
QName portName = new QName(
        "http://example.com",
        "StockQuote");
QName operationName = new QName(
        "http://example.com",
        "getLastTradePrice");
javax.xml.rpc.Call call = null;
try {
call = service.createCall(portName, operationName);
} catch (ServiceException e) {
// 異常時の処理
}
 
// サービス呼び出し
// 入力パラメータを生成
Class inputClass =((com.cosminexus.cws.xml.rpc.Call)
call).getParameterClassByName("in0");
Object in0 = null;
 
try {
    if (inputClass != null) {
        if (inputClass.getName().equals("com.example.TradeDate")) {
            in0 = inputClass.newInstance();
 
// メンバメソッドをリフレクトするMethodオブジェクトを取得
            Class[] parameterTypes = {String.class};
            Method method = inputClass.getMethod("setDate", parameterTypes);
 
// メンバメソッドを実行
            Object[] initargs = {"20070101"};
            method.invoke(in0, initargs);
        }
    }
} catch (Exception e) {
// 異常時の処理
}
Object[] inParams = new Object[]{in0};
 
Object ret = null;
try {
    ret = call.invoke(inParams);
} catch (RemoteException e) {
// 異常時の処理
    Throwable cause = e.getCause();
    if (cause instanceof C4Fault) {
        C4Fault fault = (C4Fault)cause;
 
// 例外メッセージの取得
        String msg = fault.getMessage();
        System.out.println(msg);
 
        Throwable uerr = fault.getCause();
        if (uerr != null) {
// ユーザ定義例外が含まれる場合
            Class errClass = uerr.getClass();
 
            int errcode = 0;
            try {
                if (errClass != null) {
                    if (errClass.getName().equals(
                        "com.example.TradePriceException")) {
                        Class[] clParam = {};
                        Object[] objParam = {};
 
 // メンバメソッドをリフレクトするMethodオブジェクトを取得
                        Method method = errClass.getMethod(
                                       "getErrcode", clParam);
 
// メンバメソッドを実行し,戻り値を取得
                        Object retErrcode = method.invoke(uerr, objParam);
                        if (retErrcode.getClass() == Integer.class) {
                            errcode = ((Integer)retErrcode).intValue();
                        }
                    }
                }
            } catch (Exception ex) {
// 異常時の処理
            }
            System.out.println("errcode : " + errcode);
        } else {
// ユーザ定義例外が含まれない場合
// C4Fault例外からSOAP Faultの情報を取得する
        }
    }
}
 
// 戻り値の処理
Class retClass = ret.getClass();
int price = 0;
try {
if (retClass != null) {
    if (retClass.getName().equals("com.example.TradePrice")) {
        Class[] clParam = {};
        Object[] objParam = {};
 
// メンバメソッドをリフレクトするMethodオブジェクトを取得
            Method method = retClass.getMethod("getPrice", clParam);
 
// メンバメソッドを実行し,戻り値を取得
            Object retPrice = method.invoke(ret, objParam);
            if (retPrice.getClass() == Integer.class) {
                price = ((Integer)retPrice).intValue();
            }
        }
    }
} catch (Exception e) {
// 異常時の処理
}
System.out.println("price : " + price);
 
} finally {
// クライアント識別子と実行スレッドの関連づけを解除する
Management.disconnectClientIDtoCurrentThread(cltID);
 
// SOAPクライアントの終了
Management.finalizeClient(cltID);
}

例では,javax.xml.rpc.Callクラスとcom.cosminexus.cws.xml.rpc.Callクラスという二つのCallクラスが使われています。Javaでは,別パッケージに存在する,同じ名前のクラスをimport宣言に書けないため,同じクラス内でjavax.xml.rpc.Callクラスとcom.cosminexus.cws.xml.rpc.Callクラスを使用する場合には,例のように完全修飾名で指定する必要があります。