Interstage Application Server SOAPサービス ユーザーズガイド
目次 索引 前ページ次ページ

第5章 RPC方式のアプリケーションの実装> 5.4 DII方式によるRPCクライアントアプリケーション

5.4.2 ユーザ定義型を使用するRPCクライアントアプリケーション(DII方式)

 パラメタおよび返り値にユーザ定義型を使用する場合の説明をします。ユーザ定義型として使用できる型については、“サポートされるデータ型”を参照してください。
 以下に構造体型を使用するサンプルプログラムSampleRpcCL3.javaを例に用いて、ユーザ定義型の処理を説明します。

 import javax.xml.rpc.Call;
 import javax.xml.rpc.ParameterMode;
 import javax.xml.rpc.Service;
 import javax.xml.rpc.ServiceFactory;
 import javax.xml.rpc.NamespaceConstants;
 import javax.xml.rpc.encoding.TypeMappingRegistry;
 import javax.xml.rpc.encoding.TypeMapping;
 import javax.xml.soap.SOAPElement;
 import javax.xml.soap.Detail;
 import javax.xml.namespace.QName;
 import java.util.Map;
 import java.util.Iterator;

 import com.fujitsu.interstage.soapx.encoding.ser.BeanSerializerFactory;
 import com.fujitsu.interstage.soapx.encoding.ser.BeanDeserializerFactory;

 public class SampleRpcCL3
 {
  public static void main( String[] args )
  {
   try {
    String endpointURL = "http://localhost/issoapx/servlet/SoapxServlet";
    String serviceURI = "urn:StructSample";
    QName operationName = new QName( serviceURI, "opStruct1" );
    //**(1)**
    QName dataType = new QName( serviceURI, "Struct1" );

    Service service = ServiceFactory.newInstance()
          .createService(new QName( serviceURI, "StructSampleService" ));
    Call call = service.createCall();

    //**(2)**
    TypeMappingRegistry tmr = service.getTypeMappingRegistry();
    TypeMapping tm = tmr.createTypeMapping();
    tm.register( Struct1.class, dataType,
          new BeanSerializerFactory( Struct1.class, dataType ),
          new BeanDeserializerFactory( Struct1.class, dataType ));
    tmr.register( NamespaceConstants.NSURI_SOAP_ENCODING, tm );

    call.setTargetEndpointAddress(endpointURL);
    call.setOperationName(operationName);

    call.addParameter( "arg1", dataType, ParameterMode.IN );
    call.addParameter( "arg2", dataType, ParameterMode.IN );
    call.addParameter( "arg3", dataType, ParameterMode.OUT );
    call.setReturnType(dataType);

    Struct1 arg1 = new Struct1(100,"aaaaaaaaaa");
    Struct1 arg2 = new Struct1(200,"bbbbbbbbbb");
    Object[] param = new Object[] {arg1, arg2};

    System.out.println( "arg1.a = " + arg1.a );
    System.out.println( "arg1.b = " + arg1.b );
    System.out.println( "arg2.a = " + arg2.a );
    System.out.println( "arg2.b = " + arg2.b );

    Struct1 ret = (Struct1)call.invoke( param );

    Map outParams = call.getOutputParams();
    Struct1 arg3 = (Struct1)outParams.get("arg3");

    System.out.println( "arg3.a = " + arg3.a );
    System.out.println( "arg3.b = " + arg3.b );
    System.out.println( "ret.a = " + ret.a );
    System.out.println( "ret.b = " + ret.b );

   } catch( javax.xml.rpc.ServiceException e ) {
    e.printStackTrace();
    if( e.getLinkedCause() != null ) {
     e.getLinkedCause().printStackTrace();
    }
   } catch( javax.xml.rpc.soap.SOAPFaultException e ) {
    e.printStackTrace();
    System.out.println(" Code = " + e.getFaultCode());
    System.out.println(" String = " + e.getFaultString());
    System.out.println(" Actor = " + e.getFaultActor());
    if( e.getDetail() != null ) {
     Detail detail = e.getDetail();
     Iterator it = detail.getDetailEntries();
     if( it != null ) {
      while(it.hasNext()) {
       SOAPElement elm = (SOAPElement)it.next();
       System.out.println(" Detail = " + elm);
      }
     }
    }
   } catch( javax.xml.rpc.JAXRPCException e ) {
    e.printStackTrace();

    if( e.getLinkedCause() != null ) {
     e.getLinkedCause().printStackTrace();
    }
   } catch( java.rmi.RemoteException e ) {
    e.printStackTrace();
    if( e.detail != null ) {
     e.detail.printStackTrace();
    }
   } catch( Throwable e ) {
    e.printStackTrace();
   }
  }
 }

■使用するユーザ定義型

 上記のサンプルプログラムSampleRpcCL3.javaでは、呼び出すRPCサーバアプリケーションのパラメタと返り値に以下の構造体型を使用しています。

 public class Struct1
 {
  public int a;
  public String b;

  public Struct1() {}

  public Struct1( int a, String b )
  {
   this.a = a;
   this.b = b;
  }

  public void setA( int a )
  {
   this.a = a;
  }
  public int getA()
  {
   return this.a;
  }

  public void setB( String b )
  {
   this.b = b;
  }
  public String getB()
  {
   return this.b;
  }
 }

 ユーザ定義型として構造体型を使用する場合はJavaBeanのルールに従ってJavaクラスを定義する必要があります。クラスメンバはpublicなメンバとして定義されるか、privateで定義される場合はpublicなset/getメソッドを持たなければなりません。この例で使用するStruct1クラスはpublicメンバのみを持ち、publicなset/getメソッドも持ちます。

■ユーザ定義型情報の用意

 RPC呼び出しに使用するユーザ定義パラメタ型の情報を用意します。−(1)

用意する情報はサービスのWSDL等に定義される以下の情報です。
・ユーザ定義型名のネームスペース名とローカル名(例ではdataType)

■Javaのデータ型とXMLのデータ型の対応付け情報の登録

 ユーザ定義のJavaのデータ型とXMLのデータ型を変換するための対応付け情報を“タイプマッピング”と呼び、TypeMappingオブジェクトで表します。
 TypeMappingオブジェクトには、対応付けるJavaのデータ型情報(Classオブジェクト)とXMLのデータ型情報(QNameオブジェクト)のほかに、データ型の種類に応じたシリアライザファクトリとデシリアライザファクトリを登録します。ユーザ定義のデータ型の種類には、構造体型、Bean型、列挙型があります。
 サンプルプログラムSampleRpcCL3.javaでは構造体型を使用しているので、シリアライザファクトリはcom.fujitsu.interstage.soapx.encoding.ser.BeanSerializerFactoryになり、デシリアライザファクトリはcom.fujitsu.interstage.soapx.encoding.ser.BeanDeserializerFactoryになります。詳細については“サポートされるデータ型”を参照してください。−(2)

 タイプマッピングは、TypeMappingオブジェクトをTypeMappingRegistryオブジェクトにregisterメソッドで登録することで有効になります。サンプルプログラムSampleRpcCL3.javaでは、Struct1クラスのみをユーザ定義型として使用しているため、タイプマッピングを1つだけ登録していますが、複数のユーザ定義型を使用する場合は、ユーザ定義型の数だけタイプマッピングの登録する必要があります。


目次 索引 前ページ次ページ

Copyright 2003 FUJITSU LIMITED