4.5.4 ユーザ定義のデータ型クラスを使用する場合
ユーザ定義のデータ型クラスを使用する場合のWSDLの例およびDIIのコーディング例を示します。なお,WSDLの例では次の情報が定義されています。
-
WSDLのサービス名
名前空間URI…http://example.com
ローカル名…StockQuoteService
-
WSDLのポート名
名前空間URI…http://example.com
ローカル名…StockQuote
-
WSDLのオペレーション名
名前空間URI…http://example.com
ローカル名…getLastTradePrice
-
オペレーションのパラメタ名…in0
-
XMLスキーマの複合型(パラメタに定義)
名前空間URI…http://example.com
ローカル名…TradeDate
-
XMLスキーマの複合型(戻り値に定義)
名前空間URI…http://example.com
ローカル名…TradePrice
-
XMLスキーマの複合型(ユーザ定義例外に定義)
名前空間URI…http://example.com
ローカル名…TradePriceException
(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クラスを使用する場合には,例のように完全修飾名で指定する必要があります。